24. Model building

24. Introduction

  • 이전 장에서는 선형 모델의 작동 방식을 배웠고 모델이 데이터에 대해 무엇을 말하고 있는지 이해할 수 있는 기본 도구를 배웠습니다. 이전 장에서는 시뮬레이션 된 데이터 세트에 중점을 두었습니다.

  • 이 장에서는 실제 데이터에 중점을두고 데이터 이해를 돕기 위해 점진적으로 모델을 구축하는 방법을 보여줍니다.

  • 데이터를 패턴 및 잔차로 분할하는 모델에 대해 생각할 수 있다는 사실을 이용합니다.

  • 시각화를 통해 패턴을 찾은 다음 모델을 사용하여 패턴을 구체적이고 정확하게 만듭니다.

  • 그런 다음 프로세스를 반복하되 이전 응답 변수를 모델의 잔차로 대체합니다.

  • 목표는 데이터의 내재적 지식에서 머리를 양적 모델의 명시적 지식으로 전환하는 것입니다. 이렇게하면 새 도메인에 쉽게 적용 할 수 있고 다른 도메인에서는 쉽게 사용할 수 있습니다.

  • 매우 크고 복잡한 데이터 세트의 경우 많은 작업이 필요합니다. 확실히 대안적인 접근 방식이 있습니다.

  • 더 많은 기계 학습 방식은 단순히 모델의 예측 능력에 초점을 맞추는 것입니다. 이러한 접근 방식은 블랙 박스를 생성하는 경향이 있습니다.

  • 모델은 예측을 생성하는 데 실제로 도움이되지만 실제로 이유를 알지 못합니다. 이것은 완전히 합리적인 접근 방식이지만 실제 지식을 모델에 적용하는 것을 어렵게 만듭니다.
  • 그 결과, 펀더멘털이 변함에 따라 모델이 장기간에 걸쳐 계속해서 작동 할 것인가를 평가하는 것이 어려워집니다.

  • 대부분의 실제 모델에서는 이 접근 방식과보다 고전적인 자동화 된 접근 방식을 조합하여 사용할 것을 기대합니다.

  • 멈추어야 할 때를 알기 란 쉽지 않습니다. 당신은 당신의 모델이 충분히 좋은 시점과 추가적인 투자가 성사 될 것 같지 않은 때를 알아 내야합니다.

24.1.1 Prerequisites

  • 이전 장에서 사용한 도구와 동일한 도구를 사용하지만 실제 데이터 세트 (ggplot2의 다이아몬드 및 nycflights13의 항공편)를 추가합니다.

  • 또한 항공편의 날짜 / 시간을 사용하려면 lubridate가 필요합니다.

library(tidyverse)
library(modelr)
options(na.action = na.warn)

library(nycflights13)
library(lubridate)

24.2 Why are low quality diamonds more expensive?

  • 이전 장에서 우리는 다이아몬드의 품질과 그 가격 사이의 놀라운 관계를 보았습니다

  • 품질이 낮은 다이아몬드 (빈약 한 컷, 나쁜 색상 및 열등한 선명도)는 가격이 높습니다.

ggplot(diamonds, aes(cut, price)) + geom_boxplot()

ggplot(diamonds, aes(color, price)) + geom_boxplot()

ggplot(diamonds, aes(clarity, price)) + geom_boxplot()

  • 최악의 다이아몬드 색상은 J (약간 노란색)이며 최악의 선명도는 I1 (육안으로 볼 수있는 개재물)입니다.

24.2.1 Price and carat

  • 중요한 교란 변수인 다이아몬드의 무게 (캐럿)가 있기 때문에 품질이 낮은 다이아몬드가 더 높은 가격을 갖는 것처럼 보입니다.

  • 다이아몬드의 무게는 다이아몬드의 가격을 결정하는 가장 중요한 요소이며, 품질이 낮은 다이아몬드는 더 큰 경향이 있습니다.

ggplot(diamonds, aes(carat, price)) + 
  geom_hex(bins = 50)

  • 우리는 다이아몬드의 다른 속성이 캐럿의 효과를 분리하는 모델을 피팅함으로써 상대적인 가격에 어떻게 영향을 미치는지 쉽게 알 수 있습니다.

  • 하지만 먼저 다이아몬드 데이터 세트를 조작하여 작업하기 쉽도록 두 번 조정하십시오.

  • 캐럿 미만의 다이아몬드에 집중 (데이터의 99.7 %)

  • 캐럿 및 가격 변수를 로그 변환합니다.

diamonds2 <- diamonds %>% 
  filter(carat <= 2.5) %>% 
  mutate(lprice = log2(price), lcarat = log2(carat))
ggplot(diamonds2, aes(lcarat, lprice)) + 
  geom_hex(bins = 50)

  • 로그 변환은 패턴을 선형으로 만들고 선형 패턴을 사용하기 쉽기 때문에 특히 유용합니다.

  • 다음 단계를 밟아 강렬한 선형 패턴을 제거해 봅시다. 먼저 모델을 피팅하여 패턴을 명시 적으로 만듭니다.

mod_diamond <- lm(lprice ~ lcarat, data = diamonds2)
grid <- diamonds2 %>% 
  data_grid(carat = seq_range(carat, 20)) %>% 
  mutate(lcarat = log2(carat)) %>% 
  add_predictions(mod_diamond, "lprice") %>% 
  mutate(price = 2 ^ lprice)
ggplot(diamonds2, aes(carat, price)) + 
  geom_hex(bins = 50) + 
  geom_line(data = grid, colour = "red", size = 1)

  • 다음 모델이 데이터에 대해 알려주는 것을 봅니다. 로그 변환을 실행 취소하여 예측을 역으로 변환하므로 원시 데이터에 예측을 오버레이 할 수 있습니다.

  • 우리 데이터에 대해 흥미로운 것을 알려줍니다. 모델을 믿는다면 큰 다이아몬드는 예상보다 훨씬 저렴합니다.

  • 이것은 아마도 이 데이터 세트의 다이아몬드가 1 만 9 천 달러가 들지 않기 때문일 것입니다.

  • 이제 우리는 강한 선형 패턴을 성공적으로 제거했는지 확인하는 잔차를 볼 수 있습니다.

diamonds2 <- diamonds2 %>% 
  add_residuals(mod_diamond, "lresid")
ggplot(diamonds2, aes(lcarat, lresid)) + 
  geom_hex(bins = 50)

  • 중요한 것은 이제 가격 대신 잔차를 사용하여 motivating plots을 다시 할 수 있다는 것입니다.
ggplot(diamonds2, aes(cut, lresid)) + geom_boxplot()

ggplot(diamonds2, aes(color, lresid)) + geom_boxplot()

ggplot(diamonds2, aes(clarity, lresid)) + geom_boxplot()

  • 우리는 우리가 기대하는 관계를 봅니다 : 다이아몬드의 품질이 높아질수록 상대적인 가격도 높아집니다.

  • y 축을 해석하기 위해, 우리는 잔차가 우리에게 말하는 것과 그것들이 어떤 스케일인지 생각할 필요가있다.

24.2.2 A more complicated model

  • 원한다면 모델을 계속 구축하여 관찰된 효과를 모델로 이동시켜 모델을 명시 적으로 만들 수 있습니다.

  • 예를 들어 모델에 색상, 컷 및 선명도를 포함시켜 이러한 3 가지 범주 형 변수의 효과를 명시 할 수 있습니다.

mod_diamond2 <- lm(lprice ~ lcarat + color + cut + clarity, data = diamonds2)
  • 이 모델에는 이제 4 개의 예측 변수가 포함되므로 시각화하는 것이 어려워집니다.
  • 다행히도, 그들은 현재 모두 독립되어 있어 4 개의 플롯으로 개별적으로 그릴 수 있습니다.

  • 프로세스를 좀더 쉽게하기 위해, 우리는 data_grid에 .model 인자를 사용할 것입니다

grid <- diamonds2 %>% 
  data_grid(cut, .model = mod_diamond2) %>% 
  add_predictions(mod_diamond2)
grid
ggplot(grid, aes(cut, pred)) + 
  geom_point()

  • 모델에 명시적으로 제공하지 않은 변수가 필요한 경우 data_grid ()는 자동으로 이를 “일반”값으로 채 웁니다.

  • 연속 변수의 경우 중앙값을 사용하고 범주형 변수는 가장 일반적인 값을 사용합니다.

diamonds2 <- diamonds2 %>% 
  add_residuals(mod_diamond2, "lresid2")
ggplot(diamonds2, aes(lcarat, lresid2)) + 
  geom_hex(bins = 50)

  • 이 그래프는 상당히 큰 잔차가있는 일부 다이아몬드가 있음을 나타냅니다.

  • 잔차 2는 다이아몬드가 예상했던 가격의 4배라는 것을 나타냅니다.

  • 비정상적인 값을 개별적으로 보는 것이 종종 유용합니다.

diamonds2 %>% 
  filter(abs(lresid2) > 1) %>% 
  add_predictions(mod_diamond2) %>% 
  mutate(pred = round(2 ^ pred)) %>% 
  select(price, pred, carat:table, x:z) %>% 
  arrange(price)
  • 여기에 나와 있는 것은 없지만, 이것이 모델에 문제가 있는지 또는 데이터에 오류가 있는지를 고려해 볼 때 시간을 할 가치가 있습니다.

  • 데이터에 실수가 있는 경우 이는 잘못 낮은 가격으로 책정 된 다이아몬드를 구매할 수있는 기회가 될 수 있습니다.

24.2.3 Exercises (생략)

24.3 What affects the number of daily flights?

  • 언뜻 보기에 NYC를 떠나는 항공편의 수보다 훨씬 단순한 데이터 세트에 대해서도 유사한 프로세스를 진행해 보겠습니다.
  • 이 모델은 365 개의 행과 2 개의 열만있는 아주 작은 데이터 세트입니다. 완전히 실현된 모델로 끝나지는 않을 것입니다.

  • 하지만 알 수 있듯이 이 단계는 데이터를 더 잘 이해하는 데 도움이됩니다. 하루에 비행 수를 계산하고 ggplot2로 시각화 해 봅시다.

library(nycflights13)
library(lubridate)

Attaching package: ‘lubridate’

The following objects are masked from ‘package:data.table’:

    hour, isoweek, mday,
    minute, month,
    quarter, second, wday,
    week, yday, year

The following object is masked from ‘package:base’:

    date
data(flights)
daily <- flights %>% 
  mutate(date = make_date(year, month, day)) %>% 
  group_by(date) %>% 
  summarise(n = n())
daily
ggplot(daily, aes(date, n)) + 
  geom_line()

24.3.1 Day of week

  • 장기 경향을 이해하는 것은 어려운 일입니다.

  • 그 이유는 미묘한 패턴을 지배하는 매우 강한 요일 효과가 있기 때문입니다. 요일별 항공편 번호 분포를 살펴 보겠습니다.

daily <- daily %>% 
  mutate(wday = wday(date, label = TRUE))
ggplot(daily, aes(wday, n)) + 
  geom_boxplot()

  • 대부분의 여행은 비즈니스를 위한 것이므로 주말 항공편 수가 적습니다. 그 효과는 토요일에 특히 두드러지게 나타납니다.

  • 월요일 아침 모임을 위해 일요일에 떠나는 경우도 있지만, 토요일에 가족과 함께 집에있는 것처럼 떠나는 것은 매우 드뭅니다.

  • 이 강력한 패턴을 제거하는 한 가지 방법은 모델을 사용하는 것입니다. 먼저 모델을 맞추고 원본 데이터에 예측치를 겹쳐서 표시합니다.

mod <- lm(n ~ wday, data = daily)
grid <- daily %>% 
  data_grid(wday) %>% 
  add_predictions(mod, "n")
ggplot(daily, aes(wday, n)) + 
  geom_boxplot() +
  geom_point(data = grid, colour = "red", size = 4)

daily <- daily %>% 
  add_residuals(mod)
daily %>% 
  ggplot(aes(date, resid)) + 
  geom_ref_line(h = 0) + 
  geom_line()

  • y 축의 변화에 주목하십시오. 이제 요일에 예상되는 비행 횟수와의 편차가 표시됩니다.

  • 이 플롯은 많은 요일 효과를 제거 했으므로 남아있는 더 섬세한 패턴을 볼 수 있기 때문에 유용합니다.

  • 우리 모델은 6월부터 실패 할 것으로 보입니다. 우리 모델이 포착하지 않은 강력한 규칙적인 패턴을 여전히 볼 수 있습니다. 매주 한 줄씩 줄을 그리면 그 원인을 쉽게 알 수 있습니다.

ggplot(daily, aes(date, resid, colour = wday)) + 
  geom_ref_line(h = 0) + 
  geom_line()

  • 우리 모델은 토요일에 비행 횟수를 정확히 예측하지 못합니다.

  • 여름에는 예상보다 많은 항공편이 있고, 가을에는 더 적은 항공편이 있습니다. 다음 섹션에서이 패턴을 캡처하는 방법을 더 잘 이해할 수 있습니다.

  • 예상보다 훨씬 적은 항공편으로 수 일이 있습니다.

daily %>% 
  filter(resid < -100)
  • 미국의 공휴일에 익숙하다면 7 월 4 일, 추수 감사절과 크리스마스를 볼 수 있습니다.

  • 공휴일과 일치하지 않는 것 몇 가지가 있습니다. 연습 문제 중 하나에서 작업 할 것입니다.

  • 1 년 동안 장기간에 걸쳐보다 매끄러운 추세가 나타납니다. geom_smooth ()를 사용하여 이러한 추세를 강조 할 수 있습니다.

daily %>% 
  ggplot(aes(date, resid)) + 
  geom_ref_line(h = 0) + 
  geom_line(colour = "grey50") + 
  geom_smooth(se = FALSE, span = 0.20)

  • 1 월 (12 월 에는 항공편이 더 적고 여름 (5 월 -9 월)에는 더 많은 항공편이 있습니다.

  • 우리는 단지 1 년의 데이터 만 가지고 있기 때문에이 패턴을 정량적으로 많이 할 수 없습니다. 그러나 우리는 도메인 지식을 사용하여 잠재적 설명을 브레인 스토밍 할 수 있습니다.

24.3.2 Seasonal Saturday effect

  • 먼저 토요일에 비행 횟수를 정확하게 예측하지 못하게 하십시오. 시작하기 좋은 곳은 토요일에 초점을 맞추어 원시 번호로 돌아가는 것입니다.
daily %>% 
  filter(wday == "Sat") %>% 
  ggplot(aes(date, n)) + 
    geom_point() + 
    geom_line() +
    scale_x_date(NULL, date_breaks = "1 month", date_labels = "%b")

  • (데이터와 보간이 무엇인지 명확하게 하기 위해 점과 선을 모두 사용했습니다.)

  • 나는 이 패턴이 여름 휴가로 인해 일어난다고 생각합니다 : 많은 사람들이 여름에 휴가를 가지며 사람들은 휴가를 위해 토요일 여행을 꺼려하지 않습니다.

  • 이 음모를 보면 여름 휴가가 6 월 초에서 8 월 말까지라고 추측 할 수 있습니다. 2013 년 여름 방학은 6 월 26-9 월 9 일이었습니다.

  • 봄에 가을보다 가을에 토요일 비행이 더 많은 이유는 무엇입니까? 나는 미국인 친구들에게 물었고 추수 감사절과 크리스마스 휴가 때문에 가을 동안 가족 휴가를 계획하는 것이 덜 일반적이라고 제안했다. 우리는 확실히 알 수있는 데이터가 없지만 그럴듯한 작업 가설처럼 보입니다.

  • 대략 세 가지 용어를 포착하는 “term” 변수를 만들고, 우리의 작업을 음모로 확인하십시오.

term <- function(date) {
  cut(date, 
    breaks = ymd(20130101, 20130605, 20130825, 20140101),
    labels = c("spring", "summer", "fall") 
  )
}
daily <- daily %>% 
  mutate(term = term(date)) 
daily %>% 
  filter(wday == "Sat") %>% 
  ggplot(aes(date, n, colour = term)) +
  geom_point(alpha = 1/3) + 
  geom_line() +
  scale_x_date(NULL, date_breaks = "1 month", date_labels = "%b")

  • (나는 플롯에서 좋은 휴식을 취하기 위해 수동으로 날짜를 조정했다. 시각화를 사용하여 함수가하는 일을 이해하는 데 도움이되는 것은 정말 강력하고 일반적인 기술이다.)

  • 이 새로운 변수가 다른 요일에 어떤 영향을 주는지 확인하는 것이 유용합니다.

daily <- daily %>% 
  mutate(term = term(date)) 
daily %>% 
  ggplot(aes(wday, n, colour = term)) +
    geom_boxplot()

  • 용어 전반에 걸쳐 큰 변동이 있는 것처럼 보이므로 각 용어에 대해 요일별 효과를 적용하는 것이 합리적입니다.

  • 이것은 우리의 모델을 향상 시키지만, 우리가 바라는 것만 큼은 아닙니다.

daily <- daily %>% 
  mutate(term = term(date)) 
mod1 <- lm(n ~ wday, data = daily)
mod2 <- lm(n ~ wday * term, data = daily)
daily %>% 
  gather_residuals(without_term = mod1, with_term = mod2) %>% 
  ggplot(aes(date, resid, colour = model)) +
    geom_line(alpha = 0.75)

  • 모델의 예측을 원시 데이터에 겹쳐서 문제를 볼 수 있습니다.
grid <- daily %>% 
  data_grid(wday, term) %>% 
  add_predictions(mod2, "n")
ggplot(daily, aes(wday, n)) +
  geom_boxplot() + 
  geom_point(data = grid, colour = "red") + 
  facet_wrap(~ term)

  • 우리의 모델은 평균 효과를 찾는 것이지만 우리는 큰 이상 치를 많이 가지고 있으므로 평균은 전형적인 값에서 멀리 떨어지는 경향이 있습니다.

  • rlm ()을 사용하면 이 문제를 해결할 수 있습니다. 이것은 outliers의 추정치에 대한 영향을 크게 줄이고 요일 패턴을 제거하는 훌륭한 작업을 수행하는 모델을 제공합니다.

mod3 <- MASS::rlm(n ~ wday * term, data = daily)
daily %>% 
  add_residuals(mod3, "resid") %>% 
  ggplot(aes(date, resid)) + 
  geom_hline(yintercept = 0, size = 2, colour = "white") + 
  geom_line()

  • 장기적인 추세와 긍정적인 것과 부정적인 이상치를 보는 것이 훨씬 쉬워졌습니다.

24.3.3 Computed variables

  • 많은 모델과 많은 시각화를 실험하고 있다면 변수 생성을

  • 하나의 함수로 묶어 서로 다른 변환을 우연히 적용 할 기회가없는 것이 좋습니다. 예를 들어 다음과 같이 쓸 수 있습니다.

compute_vars <- function(data) {
  data %>% 
    mutate(
      term = term(date), 
      wday = wday(date, label = TRUE)
    )
}
  • 또 다른 옵션은 변환을 모델 수식에 직접 넣는 것입니다.
wday2 <- function(x) wday(x, label = TRUE)
mod3 <- lm(n ~ wday2(date) * term(date), data = daily)
  • 두 방법 모두 합리적인 방법입니다. 변형 된 변수를 명시 적으로 만드는 것은 작업을 확인하거나 시각화에 사용하려는 경우 유용합니다.

  • 그러나 여러 열을 반환하는 변형 (예 : 스플라인)을 쉽게 사용할 수 없습니다.

  • 모델 함수에 변형을 포함 시키면 모델이 자체 포함되어 있기 때문에 많은 다른 데이터 세트로 작업 할 때 좀 더 편하게 사용할 수 있습니다.

24.3.4 Time of year: an alternative approach

  • 이전 섹션에서는 모델 개선을 위해 도메인 지식 (미국 학교 용어가 여행에 미치는 영향)을 사용했습니다.

  • 모델에서 명시 적으로 지식을 사용하는 대신 데이터에 더 많은 대화 공간을 제공 할 수 있습니다.

  • 더 유연한 모델을 사용하여 관심있는 패턴을 캡처 할 수 있습니다. 간단한 선형 추세가 적합하지 않으므로 자연스러운 스플라인을 사용하여 일년 내내 매끄러운 곡선을 만들 수 있습니다.

library(splines)
mod <- MASS::rlm(n ~ wday * ns(date, 5), data = daily)
daily %>% 
  data_grid(wday, date = seq_range(date, n = 13)) %>% 
  add_predictions(mod) %>% 
  ggplot(aes(date, pred, colour = wday)) + 
    geom_line() +
    geom_point()

  • 우리는 토요일 비행 횟수에 강한 패턴을 보았습니다. 우리는 원시 데이터에서 그 패턴을 보았기 때문에 안심할 수 있습니다. 다른 접근법에서 같은 신호를 얻으면 좋은 신호입니다.

24.3.5 Exercises (생략)

24.4 Learning more about models

  • 우리는 모델링의 절대적인 면만 썼지만, 사용자가 자신의 데이터 분석을 향상시키는 데 사용할 수있는 단순하지만 일반적인 목적의 도구를 얻었기를 바랍니다. 간단하게 시작하는 것이 좋습니다!

  • 이전에 보았 듯이 매우 단순한 모델조차도 변수간의 상호 작용을 알아내는 능력에 큰 차이를 만들 수 있습니다.

  • 이 모델링 챕터는 나머지 책보다 훨씬 더 독창적입니다.

  • 나는 다소 다른 관점에서 대부분의 다른 관점으로 모델링에 접근하며, 그것에 대해 상대적으로 공간이 거의 없다. 모델링은 실제로 독자적으로 책을받을 자격이 있으므로,이 세 권의 책 중 적어도 하나를 읽는 것이 좋습니다.

  1. Statistical Modeling: A Fresh Approach by Danny Kaplan, http://www.mosaic-web.org/go/StatisticalModeling/.

  2. An Introduction to Statistical Learning by Gareth James, Daniela Witten, Trevor Hastie, and Robert Tibshirani, http://www-bcf.usc.edu/~gareth/ISL/

  3. Applied Predictive Modeling by Max Kuhn and Kjell Johnson, http://appliedpredictivemodeling.com

25. Many models

25.1 Introduction

  • 이 장에서는 많은 수의 모델을 쉽게 사용할 수 있도록 도와주는 세 가지 강력한 아이디어를 학습합니다.

  • 많은 간단한 모델을 사용하여 복잡한 데이터 세트를 더 잘 이해합니다.

  • list-columns를 사용하여 임의의 데이터 구조를 데이터 프레임에 저장합니다. 예를 들어 선형 모델을 포함하는 열을 가질 수 있습니다.

  • David Robinson의 broom 패키지를 사용하여 모델을 깔끔한 데이터로 변환합니다. 많은 양의 모델로 작업하기위한 강력한 기술입니다. 일단 깔끔한 데이터가 있으면 이전에 배운 모든 기술을 적용 할 수 있기 때문입니다.

  • 우리는 전세계의 평균 수명에 관한 데이터를 사용하여 동기 부여의 예제로 뛰어들 것으로 시작합니다.

  • 작은 데이터 세트이지만 시각화를 향상시키는 데 모델링이 얼마나 중요한지 보여줍니다.

  • 우리는 많은 수의 간단한 모델을 사용하여 가장 강력한 신호를 분할하여 남아있는 더 약한 신호를 볼 수 있습니다.

  • 모델 요약을 통해 우리가 특이 치와 비정상적인 경향을 파악하는 데 도움을 줄 수있는 방법도 살펴 봅니다.

  • 다음 섹션에서는 개별 기술에 대해 자세히 설명합니다.

  • 목록 열 데이터 구조 및 데이터 프레임에 목록을 넣는 것이 타당한 이유에 대해 자세히 배웁니다.

  • 목록 열 작성에서 목록 열을 작성하는 세 가지 주요 방법을 학습합니다.

  • 목록 열을 단순화 할 때 목록 열을 일반 원자 벡터 (또는 원자 벡터 집합)로 다시 변환하여보다 쉽게 작업 할 수 있도록하는 방법을 배웁니다.

  • broom로 깔끔한 데이터를 만들 때, broom이제공하는 모든 도구 세트에 대해 배우고 다른 유형의 데이터 구조에 어떻게 적용 할 수 있는지 살펴 봅니다.

  • 이 장은 다소 포부가 있습니다.이 책이 R에 대한 첫 번째 소개 인 경우 이 장은 어려울 것입니다. 모델링, 데이터 구조 및 반복에 대한 아이디어를 깊이 내면화해야합니다.

  • 당신이 그것을 얻지 못한다면 걱정하지 마십시오. 단지 몇 달 동안이 장을 제쳐두고 머리를 펴고 싶을 때 다시 오십시오.

25.1.1 Prerequisites

  • 많은 모델로 작업하는 것은 모델링을 용이하게하기 위해 tidyverse (데이터 탐색, 논쟁 및 프로그래밍) 및 modelr 패키지의 많은 패키지를 필요로합니다.
library(modelr)
library(tidyverse)

25.2 gapminder

  • 많은 간단한 모델의 힘을 유도하기 위해 “gapminder”데이터를 살펴볼 것입니다.

  • 이 데이터는 스웨덴의 의사이자 통계 학자 인 Hans Rosling에 의해 대중화되었습니다. 너는 그 사람에 대해 들어 본 적이 없다면, 지금 당장이 장을 읽지 말고 그의 비디오를 보아라.

  • 그는 환상적인 데이터 발표자이며 데이터를 사용하여 매력적인 이야기를 표현하는 방법을 보여줍니다. 시작하기 좋은 곳은 BBC와 공동으로 촬영 한 짧은 동영상입니다. https://www.youtube.com/watch?v=jbkSRLYSojo.

  • gapminder 데이터는 기대 수명과 GDP와 같은 통계를보고 시간 경과에 따른 국가의 진행을 요약합니다. gapminder 패키지를 만든 Jenny Bryan 덕분에 데이터는 R에서 쉽게 액세스 할 수 있습니다.

library(gapminder)
gapminder
  • 이 사례 연구에서 우리는 “각 국가 (국가)에 대한 기대 수명 (lifeExp)이 시간에 따라 어떻게 변하는가?”라는 질문에 답하기 위해 세 가지 변수에만 초점을 맞출 것입니다. 시작하기 좋은 곳은 줄거리입니다.
gapminder %>% 
  ggplot(aes(year, lifeExp, group = country)) +
    geom_line(alpha = 1/3)

  • 이것은 작은 데이터 세트입니다. 단지 1,700 개의 관측치와 3 개의 변수 만 있습니다.

  • 그러나 계속 진행되는 것을 보기가 여전히 어렵습니다! 전반적으로 기대 수명이 꾸준히 개선되고있는 것처럼 보입니다.
  • 그러나 자세히 살펴보면 이 패턴을 따르지 않는 국가가 있음을 알 수 있습니다. 우리는 어떻게 이들 국가를보다 쉽게 볼 수 있습니까?

  • 한 가지 방법은 지난 장에서와 동일한 접근법을 사용하는 것입니다.

  • 더 세밀한 추세를 보지 못하게하는 강력한 신호 (전반적인 선형 성장)가 있습니다. 우리는 선형 추세를 가진 모델을 피팅함으로써 이러한 요소들을 구분할 것입니다. 이 모델은 시간이 지남에 따라 꾸준히 성장하고 나머지는 남아있는 것을 보여줍니다.

  • 당신은 이미 우리가 하나의 국가를 가졌다면 그것을하는 법을 알고 있습니다

nz <- filter(gapminder, country == "New Zealand")
nz %>% 
  ggplot(aes(year, lifeExp)) + 
  geom_line() + 
  ggtitle("Full data = ")

nz_mod <- lm(lifeExp ~ year, data = nz)
nz %>% 
  add_predictions(nz_mod) %>%
  ggplot(aes(year, pred)) + 
  geom_line() + 
  ggtitle("Linear trend + ")

nz %>% 
  add_residuals(nz_mod) %>% 
  ggplot(aes(year, resid)) + 
  geom_hline(yintercept = 0, colour = "white", size = 3) + 
  geom_line() + 
  ggtitle("Remaining pattern")

25.2.1 Nested data

  • 이 코드를 여러 번 복사하여 붙여 넣는 것을 상상해보십시오. 그러나 당신은 이미 더 나은 방법을 배웠습니다!

  • 함수로 공통 코드를 추출하고 purrr의 map 함수를 사용하여 반복합니다. 이 문제는 이전에 본 것과 약간 다르게 구성됩니다.

  • 각 변수에 대해 액션을 반복하는 대신, 행의 하위 집합 인 각 국가에 대해 액션을 반복합니다. 그렇게하기 위해서는 새로운 데이터 구조 인 중첩 된 데이터 프레임이 필요합니다.

  • 중첩 된 데이터 프레임을 만들려면 그룹화 된 데이터 프레임으로 시작하여 “중첩”합니다.

by_country <- gapminder %>% 
  group_by(country, continent) %>% 
  nest()
by_country
  • (나는 대륙과 국가를 구분하여 조금씩 부정하고있다. 주어진 국가, 대륙은 고정되어 있으므로 더 이상 그룹을 추가하지 않지만 추가 변수를 타고 쉽게 탈 수있다.)

  • 이렇게하면 그룹당 하나의 행 (국가 별)과 약간 특이한 열 (데이터)이있는 데이터 프레임이 만들어집니다.

  • 데이터는 데이터 프레임 (또는 정확한 것)의 목록입니다. 이것은 미친 아이디어처럼 보입니다.

  • 우리는 다른 데이터 프레임의 목록 인 열이있는 데이터 프레임을 가지고 있습니다!

  • 나는 이것이 왜 좋은 생각이라고 생각하는지 곧 설명 할 것이다.

  • 데이터 열은 다소 복잡하기 때문에 보기가 까다 롭습니다. 우리는 여전히 이러한 개체를 탐색하는 데 유용한 도구를 사용하고 있습니다.

  • 불행히도 str ()을 사용하는 것은 권장하지 않습니다. 왜냐하면 종종 매우 긴 출력을 생성하기 때문입니다.

  • 그러나 데이터 열에서 단일 요소를 뽑으면 해당 국가 (이 경우 아프가니스탄)의 모든 데이터가 포함되어 있음을 알 수 있습니다.

by_country$data[[1]]
  • 표준 그룹화 된 데이터 프레임과 중첩 된 데이터 프레임의 차이점에 유의하십시오.

  • 그룹화 된 데이터 프레임에서 각 행은 관찰입니다. 중첩 된 데이터 프레임에서 각 행은 그룹입니다.

  • 중첩 된 데이터 세트에 대해 생각해 볼 수있는 또 다른 방법은 이제 메타 뷰를 얻는 것입니다.

  • 하나의 시점이 아닌 국가의 전체 시간 코스를 나타내는 행입니다.

25.2.2 List-columns

  • 이제 중첩 된 데이터 프레임이 생겨서 일부 모델을 적합하게 만들 수 있습니다. 모델 적합 함수가 있습니다.

  • 그리고 모든 데이터 프레임에 적용하려고합니다. 데이터 프레임은 목록에 있으므로 purrr :: map ()을 사용하여 각 요소에 country_model을 적용 할 수 있습니다.

country_model <- function(df) {
  lm(lifeExp ~ year, data = df)
}
models <- map(by_country$data, country_model)
  • 그러나 모델 목록을 자유롭게 떠 다니는 개체로 남겨두기보다는 by_country 데이터 프레임에 열로 저장하는 것이 더 좋습니다.

  • 관련 객체를 열에 저장하는 것은 데이터 프레임의 핵심 부분이며 왜 목록 열이 그렇게 좋은 생각인지 생각합니다.

  • 이 국가들과 일하는 과정에서 우리는 국가마다 요소가 하나씩있는 많은 목록을 갖게 될 것입니다.

  • 그렇다면 이 모든 것을 하나의 데이터 프레임에 모두 저장하지 않는 이유는 무엇입니까?

  • 다시 말해 전역 환경에서 새 객체를 만드는 대신 by_country 데이터 프레임에 새 변수를 만들 것입니다. dplyr :: mutate ()에 대한 작업입니다.

by_country <- by_country %>% 
  mutate(model = map(data, country_model))
by_country
  • 이는 모든 장점이 있습니다. 왜냐하면 모든 관련 오브젝트가 함께 저장되기 때문에 필터링하거나 정렬 할 때 수동으로 동기화 할 필요가 없습니다.

  • 데이터 프레임의 의미는 다음과 같이 처리합니다.

by_country %>% 
  filter(continent == "Europe")
by_country %>% 
  arrange(continent, country)
  • 데이터 프레임 목록과 모델 목록이 별개의 객체 인 경우 하나의 벡터를 재정렬하거나 하위 집합 할 때마다 모든 벡터 객체를 재정렬하거나 하위 집합을 동기화하여 동기화 상태로 유지해야한다는 점을 기억해야합니다.

  • 잊어 버리면 코드는 계속 작동하지만 잘못된 대답을 줄 것입니다.

25.2.3 Unnesting

  • 이전에는 단일 데이터 세트로 단일 모델의 잔차를 계산했습니다.

  • 이제 142 개의 데이터 프레임과 142 개의 모델이 있습니다. 잔차를 계산하려면 add_residuals ()를 각 모델 - 데이터 쌍과 함께 호출해야합니다.

by_country <- by_country %>% 
  mutate(
    resids = map2(data, model, add_residuals)
  )
by_country
  • 그러나 데이터 프레임 목록을 어떻게 그릴 수 있습니까?

  • 그 질문에 답하기 위해 고군분투하는 대신, 데이터 프레임 목록을 일반 데이터 프레임으로 돌려 보겠습니다.

  • 이전에는 일반 데이터 프레임을 중첩 데이터 프레임으로 바꾸기 위해 nest ()를 사용했으며 이제는 unnest ()와 반대의 작업을 수행합니다.

resids <- unnest(by_country, resids)
resids
  • 각 일반 열은 중첩 열의 각 행마다 하나씩 반복됩니다.

  • 이제 우리는 정규 데이터 프레임을 가지고 있습니다. 잔차를 그릴 수 있습니다.

resids %>% 
  ggplot(aes(year, resid)) +
    geom_line(aes(group = country), alpha = 1 / 3) + 
    geom_smooth(se = FALSE)

#> `geom_smooth()` using method = 'gam'
  • 대륙 별 facetting은 특히 드러납니다 :
resids %>% 
  ggplot(aes(year, resid, group = country)) +
    geom_line(alpha = 1 / 3) + 
    facet_wrap(~continent)

  • 가벼운 패턴을 놓친 것처럼 보입니다. 아프리카에서도 계속 진행중인 흥미로운 점이 있습니다. 매우 큰 잔차가 있음을 알 수 있습니다.

  • 이는 우리 모델이 거기에서 잘 맞지 않는다는 것을 의미합니다. 우리는 다음 섹션에서 좀 더 다른 각도에서 공격 해 보겠습니다.

25.2.4 Model quality

  • 모델에서 잔차를 보는 대신 모델 품질에 대한 일반적인 측정을 볼 수 있습니다.

  • 이전 장에서 몇 가지 구체적인 측정 방법을 배웠습니다. 여기에서는 broom 패키지를 사용하는 다른 접근 방법을 보여줍니다.

  • broom 꾸러미는 모델을 깔끔한 데이터로 바꾸기위한 일반적인 기능 세트를 제공합니다.

  • 여기서는 broom :: glance ()를 사용하여 일부 모델 품질 메트릭을 추출합니다.

  • 모델에 적용하면 단일 행이있는 데이터 프레임이 생성됩니다.

broom::glance(nz_mod)
by_country %>% 
  mutate(glance = map(model, broom::glance)) %>% 
  unnest(glance)
  • 여전히 모든 목록 열을 포함하기 때문에 우리가 원하는 결과물이 아닙니다. unnest ()가 단일 행 데이터 프레임에서 작동 할 때의 기본 동작입니다. 이 열을 억제하려면 .drop = TRUE를 사용합니다.
glance <- by_country %>% 
  mutate(glance = map(model, broom::glance)) %>% 
  unnest(glance, .drop = TRUE)
glance
  • (인쇄되지 않은 변수에주의를 기울이십시오. 유용한 정보가 많이 있습니다.)

  • 이 데이터 프레임을 사용하면 잘 맞지 않는 모델을 찾을 수 있습니다.

glance %>% 
  arrange(r.squared)
  • 최악의 모델은 모두 아프리카에있는 것처럼 보입니다.

  • 그걸 플롯으로 두 번 확인해 봅시다. 여기에는 상대적으로 적은 수의 관측 값과 이산 변수가 있으므로 geom_jitter ()가 효과적입니다.

glance %>% 
  ggplot(aes(continent, r.squared)) + 
    geom_jitter(width = 0.5)

  • We could pull out the countries with particularly bad R2 and plot the data:
bad_fit <- filter(glance, r.squared < 0.25)
gapminder %>% 
  semi_join(bad_fit, by = "country") %>% 
  ggplot(aes(year, lifeExp, colour = country)) +
    geom_line()

  • 우리는 HIV / AIDS 전염병과 르완다 대량 학살의 비극이라는 두 가지 주요 효과를 여기에서 보았습니다.

25.2.5 Exercises (생략)

25.3 List-columns

  • 이제는 여러 모델을 관리하기 위한 기본 워크 플로를 보았으므로 몇 가지 세부 사항으로 돌아가 보겠습니다.

  • 이 섹션에서는 목록 열 데이터 구조에 대해 좀 더 자세히 살펴 보겠습니다.

  • 최근에 나는 목록 열에 대한 아이디어를 정말로 높이 평가했습니다. 목록 - 열은 데이터 프레임의 정의에 내포되어 있습니다.

  • 데이터 프레임은 동일한 길이 벡터의 명명 된 목록입니다.

  • 목록은 벡터이므로 목록을 데이터 프레임의 열로 사용하는 것이 항상 올바른 방법입니다.

  • 그러나 기본 R은 목록 열을 쉽게 만들 수 없으며 data.frame ()은 목록을 열 목록으로 처리합니다.

data.frame(x = list(1:3, 3:5))
data.frame(
  x = I(list(1:3, 3:5)), 
  y = c("1, 2", "3, 4, 5")
)
  • Tibble은 lazier (tibble ()이 입력을 수정하지 않음) 및 더 나은 인쇄 방법을 제공하여이 문제를 완화합니다.
tibble(
  x = list(1:3, 3:5), 
  y = c("1, 2", "3, 4, 5")
)
tribble(
   ~x, ~y,
  1:3, "1, 2",
  3:5, "3, 4, 5"
)
  • 목록 - 열은 종종 중간 데이터 구조로 가장 유용합니다.

  • 대부분의 R 함수는 원자 벡터 또는 데이터 프레임에서 작동하기 때문에 직접 작업하기가 어렵지만 관련 항목을 데이터 프레임에 유지하는 이점은 약간의 번거 로움이 따릅니다.

  • 일반적으로 효과적인 목록 - 열 파이프 라인의 세 부분이 있습니다.

  • list-columns 만들기에 설명 된 것처럼 nest (), summarize () + list () 또는 mutate () + map 함수 중 하나를 사용하여 list-column을 만듭니다.

  • map (), map2 () 또는 pmap ()을 사용하여 기존 목록 열을 변형하여 다른 중간 목록 열을 작성합니다.

  • 예를 들어, 위의 사례 연구에서 데이터 프레임의 목록 - 열을 변형하여 모델의 목록 - 열을 만들었습니다.

  • 목록 열 단순화에서 설명한대로 목록 열을 데이터 프레임 또는 원자 벡터로 다시 단순화합니다.

25.4 Creating list-columns

  • 일반적으로 tibble ()을 사용하여 목록 열을 만들지 않습니다.

  • 대신 다음 세 가지 방법 중 하나를 사용하여 일반 열에서 생성합니다.

  • tidyr :: nest ()를 사용하여 그룹화 된 데이터 프레임을 데이터 프레임 목록 - 열이있는 중첩 데이터 프레임으로 변환합니다.

  • mutate () 및 벡터화 된 함수를 사용하여 목록을 반환합니다.

  • 여러 결과를 반환하는 summarize () 및 요약 함수.

  • 또는 tibble :: enframe ()을 사용하여 명명 된 목록에서 생성 할 수도 있습니다.

  • 일반적으로 목록 열을 만들 때 동질성인지 확인해야합니다. 각 요소에는 동일한 유형의 것이 포함되어야합니다.

  • 이것이 사실인지 확인하는 검사는 없지만, purrr을 사용하고 타입 안정 함수에 대해 배운 것을 기억한다면, 자연스럽게 발견되어야합니다.

25.4.1 With nesting

  • nest ()는 데이터 프레임의 목록 열이있는 데이터 프레임 인 중첩 데이터 프레임을 만듭니다.

  • 중첩 된 데이터 프레임에서 각 행은 메타 관측입니다. 다른 열은 관측을 정의하는 변수 (위의 국가 및 대륙과 같은)를 제공하고 데이터 프레임의 목록 열은 메타 관측을 구성하는 개별 관측을 제공합니다.

  • nest ()를 사용하는 두 가지 방법이 있습니다.

  • 지금까지 그룹화 된 데이터 프레임과 함께 사용하는 방법을 살펴 보았습니다. 그룹화 된 데이터 프레임에 적용되면 nest ()는 그룹화 열을 그대로 유지하고 그 외 모든 항목을 list-column에 묶습니다.

gapminder %>% 
  group_by(country, continent) %>% 
  nest()
  • 또한 그룹화되지 않은 데이터 프레임에이 열을 사용하여 중첩 할 열을 지정할 수 있습니다.
gapminder %>% 
  nest(year:gdpPercap)

25.4.2 From vectorised functions

  • 유용한 함수 중 일부는 원자 벡터를 사용하여 목록을 반환합니다.

  • 예를 들어, 문자열에서 문자 벡터를 취하고 문자 벡터 목록을 반환하는 stringr :: str_split ()에 대해 배웠습니다.

  • mutate 내부에서 이를 사용하면 list-column을 얻을 수 있습니다.

df <- tribble(
  ~x1,
  "a,b,c", 
  "d,e,f,g"
) 
df %>% 
  mutate(x2 = stringr::str_split(x1, ","))
df %>% 
  mutate(x2 = stringr::str_split(x1, ",")) %>% 
  unnest()
  • (이 패턴을 많이 사용하는 경우,이 공통 패턴을 감싸는 래퍼 인 tidyr : separate_rows ()를 확인하십시오.

  • 이 패턴의 다른 예는 purrr에서 map (), map2 (), pmap ()을 사용하는 것입니다. 예를 들어, 다른 함수를 호출하여 마지막 예제를 가져 와서 mutate ()를 사용하도록 다시 작성할 수 있습니다.

sim <- tribble(
  ~f,      ~params,
  "runif", list(min = -1, max = -1),
  "rnorm", list(sd = 5),
  "rpois", list(lambda = 10)
)
sim %>%
  mutate(sims = invoke_map(f, params, n = 10))
  • 기술적으로 sim은 두 배와 정수 벡터를 모두 포함하고 있기 때문에 균질하지 않습니다.

  • 그러나 정수 및 복식은 모두 숫자 벡터이므로 많은 문제가 발생하지는 않습니다.

25.4.3 From multivalued summaries

  • summarize ()의 한 가지 제한 사항은 단일 값을 리턴하는 요약 함수에서만 작동한다는 것입니다.

  • 즉, 임의의 길이의 벡터를 리턴하는 quantile ()과 같은 함수와 함께 사용할 수 없다는 것을 의미합니다.

mtcars %>% 
  group_by(cyl) %>% 
  summarise(q = quantile(mpg))
  • 그러나 목록에 결과를 래핑 할 수는 있습니다. 이것은 각 요약이 이제 길이 1의 목록 (벡터)이므로 summarize ()의 계약을 따릅니다.
mtcars %>% 
  group_by(cyl) %>% 
  summarise(q = list(quantile(mpg)))
  • 불충분 한 결과를 얻으려면 다음과 같은 가능성을 포착해야합니다.
probs <- c(0.01, 0.25, 0.5, 0.75, 0.99)
mtcars %>% 
  group_by(cyl) %>% 
  summarise(p = list(probs), q = list(quantile(mpg, probs))) %>% 
  unnest()

25.4.4 From a named list

  • 목록 열이있는 데이터 프레임은 일반적인 문제에 대한 해결책을 제공합니다.

  • 목록의 내용과 해당 요소를 반복 할 경우 어떻게합니까? 모든 것을 하나의 객체로 묶는 대신 데이터 프레임을 만드는 것이 더 쉽습니다.

  • 한 열에는 요소가 포함될 수 있고 한 열에는 목록이 포함될 수 있습니다.

  • 목록에서 그러한 데이터 프레임을 생성하는 쉬운 방법은 tibble :: enframe ()입니다.

x <- list(
  a = 1:5,
  b = 3:4, 
  c = 5:6
) 
df <- enframe(x)
df
  • 이 구조의 장점은 간단합니다. 이름은 메타 데이터의 문자 벡터가 있으면 유용하지만 다른 유형의 데이터가 있거나 여러 벡터가 있으면 도움이 되지 않습니다.

  • 이제 이름과 값을 병렬로 반복하려는 경우 map2()를 사용할 수 있습니다.

df %>% 
  mutate(
    smry = map2_chr(name, value, ~ stringr::str_c(.x, ": ", .y[1]))
  )

25.4.5 Exercises (생략)

25.5 Simplifying list-columns

  • 이 책에서 배웠던 데이터 조작 및 시각화 기술을 적용하려면 list-column을 일반 열 (원자 벡터) 또는 열 집합으로 다시 단순화해야합니다.

  • 더 간단한 구조로 다시 축소하기 위해 사용하는 기술은 요소 당 하나의 값 또는 여러 값 중 원하는 값에 따라 다릅니다.

  • 단일 값을 원할 경우 map_lgl (), map_int (), map_dbl () 및 map_chr ()에 mutate ()를 사용하여 원자 벡터를 만듭니다.

  • 많은 값을 원하면 unnest ()를 사용하여 목록 열을 일반 열로 다시 변환하고 필요한만큼 행을 반복하십시오.

25.5.1 List to vector

  • 목록 열을 원자 벡터로 줄일 수 있으면 일반 열이됩니다. 예를 들어, 타입과 길이를 가진 객체를 항상 요약 할 수 있으므로,이 코드는 여러분이 가지고있는 list-column의 종류에 관계없이 작동합니다 :
df <- tribble(
  ~x,
  letters[1:5],
  1:3,
  runif(5)
)
  
df %>% mutate(
  type = map_chr(x, typeof),
  length = map_int(x, length)
)
  • 이것은 기본 tbl 인쇄 방법에서 얻은 기본 정보와 동일하지만 필터링을 위해 사용할 수 있습니다.

  • 이기종 목록을 가지고 있고 그 부분을 걸러 내고 싶다면 유용한 기법입니다.

  • 지도 _ * () 단축키를 잊지 마세요. map_chr (x, “apple”)을 사용하여 x의 각 요소에 대해 apple에 저장된 문자열을 추출 할 수 있습니다.

  • 중첩 된 목록을 일반 열로 끌어 올 때 유용합니다. null를 반환하는 대신 요소가 누락 된 경우 사용할 값을 제공하려면 .null 인수를 사용하십시오.

df <- tribble(
  ~x,
  list(a = 1, b = 2),
  list(a = 2, c = 4)
)
df %>% mutate(
  a = map_dbl(x, "a"),
  b = map_dbl(x, "b", .null = NA_real_)
)

25.5.2 Unnesting

  • unnest ()는 list-column의 각 요소에 대해 한 번씩 일반 열을 반복하여 작동합니다. 예를 들어, 다음의 아주 간단한 예제에서 첫 번째 행을 4 번 반복합니다 (y의 첫 번째 요소는 길이가 4이므로). 두 번째 행은 한 번만 반복합니다.
tibble(x = 1:2, y = list(1:4, 1)) %>% unnest(y)
  • 즉, 다른 수의 요소가 포함 된 두 개의 열을 동시에 중첩 해제 할 수 없습니다.
df1 <- tribble(
  ~x, ~y,           ~z,
   1, c("a", "b"), 1:2,
   2, "c",           3
)
df1
df1 %>% unnest(y, z)
df2 <- tribble(
  ~x, ~y,           ~z,
   1, "a",         1:2,  
   2, c("b", "c"),   3
)
df2
  • 데이터 프레임의 목록 열을 괄호에 넣을 때도 동일한 원칙이 적용됩니다. 각 행의 모든 데이터 프레임이 같은 수의 행을 가진 한 여러 list-col을 중첩 할 수 있습니다.

25.5.3 Exercises (생략)

25.6 Making tidy data with broom

  • broom 패키지는 모델을 깔끔한 데이터 프레임으로 바꾸기위한 세 가지 일반적인 도구를 제공합니다.

  • broom :: glance (model) 각 모델에 대한 행을 반환합니다. 각 열은 모델 요약을 제공합니다. 모델 요약 또는 모델 복잡성 또는 둘의 조합입니다.

  • broom :: tidy (model) 모델의 각 계수에 대한 행을 반환합니다. 각 열은 추정치 또는 그 변동성에 대한 정보를 제공합니다.

  • broom :: augment (model, data)는 데이터의 각 행에 대해 행을 반환하고 잔여와 같은 추가 값을 추가하며 통계에 영향을 줍니다.

LS0tCnRpdGxlOiAiUiBmb3IgRGF0YSBTY2llbmNlIC0gTW9kZWwgQnVpbGRpbmcgLyBNYW55IE1vZGVscyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyMgMjQuIE1vZGVsIGJ1aWxkaW5nCgojIyMgMjQuIEludHJvZHVjdGlvbgotIOydtOyghCDsnqXsl5DshJzripQg7ISg7ZiVIOuqqOuNuOydmCDsnpHrj5kg67Cp7Iud7J2EIOuwsOyboOqzoCDrqqjrjbjsnbQg642w7J207YSw7JeQIOuMgO2VtCDrrLTsl4fsnYQg66eQ7ZWY6rOgIOyeiOuKlOyngCDsnbTtlbTtlaAg7IiYIOyeiOuKlCDquLDrs7gg64+E6rWs66W8IOuwsOyboOyKteuLiOuLpC4g7J207KCEIOyepeyXkOyEnOuKlCDsi5zrrqzroIjsnbTshZgg65CcIOuNsOydtO2EsCDshLjtirjsl5Ag7KSR7KCQ7J2EIOuRkOyXiOyKteuLiOuLpC4gCgotIOydtCDsnqXsl5DshJzripQg7Iuk7KCcIOuNsOydtO2EsOyXkCDspJHsoJDsnYTrkZDqs6Ag642w7J207YSwIOydtO2VtOulvCDrj5XquLAg7JyE7ZW0IOygkOynhOyggeycvOuhnCDrqqjrjbjsnYQg6rWs7LaV7ZWY64qUIOuwqeuyleydhCDrs7Tsl6zspI3ri4jri6QuCgotIOuNsOydtO2EsOulvCDtjKjthLQg67CPIOyelOywqOuhnCDrtoTtlaDtlZjripQg66qo64247JeQIOuMgO2VtCDsg53qsIHtlaAg7IiYIOyeiOuLpOuKlCDsgqzsi6TsnYQg7J207Jqp7ZWp64uI64ukLiAKCi0g7Iuc6rCB7ZmU66W8IO2Gte2VtCDtjKjthLTsnYQg7LC+7J2AIOuLpOydjCDrqqjrjbjsnYQg7IKs7Jqp7ZWY7JesIO2MqO2EtOydhCDqtazssrTsoIHsnbTqs6Ag7KCV7ZmV7ZWY6rKMIOunjOuTreuLiOuLpC4gCgotIOq3uOufsCDri6TsnYwg7ZSE66Gc7IS47Iqk66W8IOuwmOuzte2VmOuQmCDsnbTsoIQg7J2R64u1IOuzgOyImOulvCDrqqjrjbjsnZgg7J6U7LCo66GcIOuMgOyytO2VqeuLiOuLpC4gCgotIOuqqe2RnOuKlCDrjbDsnbTthLDsnZgg64K07J6s7KCBIOyngOyLneyXkOyEnCDrqLjrpqzrpbwg7JaR7KCBIOuqqOuNuOydmCDrqoXsi5zsoIEg7KeA7Iud7Jy866GcIOyghO2ZmO2VmOuKlCDqsoPsnoXri4jri6QuIOydtOugh+qyjO2VmOuptCDsg4gg64+E66mU7J247JeQIOyJveqyjCDsoIHsmqkg7ZWgIOyImCDsnojqs6Ag64uk66W4IOuPhOuplOyduOyXkOyEnOuKlCDsib3qsowg7IKs7Jqp7ZWgIOyImCDsnojsirXri4jri6QuCgotIOunpOyasCDtgazqs6Ag67O17J6h7ZWcIOuNsOydtO2EsCDshLjtirjsnZgg6rK97JqwIOunjuydgCDsnpHsl4XsnbQg7ZWE7JqU7ZWp64uI64ukLiDtmZXsi6Ttnogg64yA7JWI7KCB7J24IOygkeq3vCDrsKnsi53snbQg7J6I7Iq164uI64ukLiAKCi0g642UIOunjuydgCDquLDqs4Qg7ZWZ7Iq1IOuwqeyLneydgCDri6jsiJztnogg66qo64247J2YIOyYiOy4oSDriqXroKXsl5Ag7LSI7KCQ7J2EIOunnuy2lOuKlCDqsoPsnoXri4jri6QuIOydtOufrO2VnCDsoJHqt7wg67Cp7Iud7J2AIOu4lOuemSDrsJXsiqTrpbwg7IOd7ISx7ZWY64qUIOqyve2WpeydtCDsnojsirXri4jri6QuIAoKLSDrqqjrjbjsnYAg7JiI7Lih7J2EIOyDneyEse2VmOuKlCDrjbAg7Iuk7KCc66GcIOuPhOybgOydtOuQmOyngOunjCDsi6TsoJzroZwg7J207Jyg66W8IOyVjOyngCDrqrvtlanri4jri6QuIOydtOqyg+ydgCDsmYTsoITtnogg7ZWp66as7KCB7J24IOygkeq3vCDrsKnsi53snbTsp4Drp4wg7Iuk7KCcIOyngOyLneydhCDrqqjrjbjsl5Ag7KCB7Jqp7ZWY64qUIOqyg+ydhCDslrTroLXqsowg66eM65Ot64uI64ukLiAKLSDqt7gg6rKw6rO8LCDtjoDrjZTrqZjthLjsnbQg67OA7ZWo7JeQIOuUsOudvCDrqqjrjbjsnbQg7J6l6riw6rCE7JeQIOqxuOyzkCDqs4Tsho3tlbTshJwg7J6R64+ZIO2VoCDqsoPsnbjqsIDrpbwg7Y+J6rCA7ZWY64qUIOqyg+ydtCDslrTroKTsm4zsp5Hri4jri6QuIAoKLSDrjIDrtoDrtoTsnZgg7Iuk7KCcIOuqqOuNuOyXkOyEnOuKlCDsnbQg7KCR6re8IOuwqeyLneqzvOuztOuLpCDqs6DsoITsoIHsnbgg7J6Q64+Z7ZmUIOuQnCDsoJHqt7wg67Cp7Iud7J2EIOyhsO2Vqe2VmOyXrCDsgqzsmqntlaAg6rKD7J2EIOq4sOuMgO2VqeuLiOuLpC4KCi0g66mI7LaU7Ja07JW8IO2VoCDrlYzrpbwg7JWM6riwIOuegCDsib3sp4Ag7JWK7Iq164uI64ukLiDri7nsi6DsnYAg64u57Iug7J2YIOuqqOuNuOydtCDstqnrtoTtnogg7KKL7J2AIOyLnOygkOqzvCDstpTqsIDsoIHsnbgg7Yis7J6Q6rCAIOyEseyCrCDrkKAg6rKDIOqwmeyngCDslYrsnYAg65WM66W8IOyVjOyVhCDrgrTslbztlanri4jri6QuIAoKIyMjIDI0LjEuMSBQcmVyZXF1aXNpdGVzCgotIOydtOyghCDsnqXsl5DshJwg7IKs7Jqp7ZWcIOuPhOq1rOyZgCDrj5nsnbztlZwg64+E6rWs66W8IOyCrOyaqe2VmOyngOunjCDsi6TsoJwg642w7J207YSwIOyEuO2KuCAoZ2dwbG90MuydmCDri6TsnbTslYTrqqzrk5wg67CPIG55Y2ZsaWdodHMxM+ydmCDtla3qs7Xtjrgp66W8IOy2lOqwgO2VqeuLiOuLpC4gCgotIOuYkO2VnCDtla3qs7XtjrjsnZgg64Kg7KecIC8g7Iuc6rCE7J2EIOyCrOyaqe2VmOugpOuptCBsdWJyaWRhdGXqsIAg7ZWE7JqU7ZWp64uI64ukLgoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KG1vZGVscikKb3B0aW9ucyhuYS5hY3Rpb24gPSBuYS53YXJuKQoKbGlicmFyeShueWNmbGlnaHRzMTMpCmxpYnJhcnkobHVicmlkYXRlKQpgYGAKCgojIyMgMjQuMiBXaHkgYXJlIGxvdyBxdWFsaXR5IGRpYW1vbmRzIG1vcmUgZXhwZW5zaXZlPwoKLSDsnbTsoIQg7J6l7JeQ7IScIOyasOumrOuKlCDri6TsnbTslYTrqqzrk5zsnZgg7ZKI7KeI6rO8IOq3uCDqsIDqsqkg7IKs7J207J2YIOuGgOudvOyatCDqtIDqs4Trpbwg67O07JWY7Iq164uI64ukIAoKLSDtkojsp4jsnbQg64Ku7J2AIOuLpOydtOyVhOuqrOuTnCAo67mI7JW9IO2VnCDsu7csIOuCmOyBnCDsg4nsg4Eg67CPIOyXtOuTse2VnCDshKDrqoXrj4Qp64qUIOqwgOqyqeydtCDrhpLsirXri4jri6QuCgpgYGB7cn0KZ2dwbG90KGRpYW1vbmRzLCBhZXMoY3V0LCBwcmljZSkpICsgZ2VvbV9ib3hwbG90KCkKZ2dwbG90KGRpYW1vbmRzLCBhZXMoY29sb3IsIHByaWNlKSkgKyBnZW9tX2JveHBsb3QoKQpnZ3Bsb3QoZGlhbW9uZHMsIGFlcyhjbGFyaXR5LCBwcmljZSkpICsgZ2VvbV9ib3hwbG90KCkKYGBgCgotIOy1nOyVheydmCDri6TsnbTslYTrqqzrk5wg7IOJ7IOB7J2AIEogKOyVveqwhCDrhbjrnoDsg4kp7J2066mwIOy1nOyVheydmCDshKDrqoXrj4TripQgSTEgKOycoeyViOycvOuhnCDrs7wg7IiY7J6I64qUIOqwnOyerOusvCnsnoXri4jri6QuCgojIyMgMjQuMi4xIFByaWNlIGFuZCBjYXJhdAotIOykkeyalO2VnCDqtZDrnoAg67OA7IiY7J24IOuLpOydtOyVhOuqrOuTnOydmCDrrLTqsowgKOy6kOufvynqsIAg7J6I6riwIOuVjOusuOyXkCDtkojsp4jsnbQg64Ku7J2AIOuLpOydtOyVhOuqrOuTnOqwgCDrjZQg64aS7J2AIOqwgOqyqeydhCDqsJbripQg6rKD7LKY65+8IOuztOyeheuLiOuLpC4gCgotIOuLpOydtOyVhOuqrOuTnOydmCDrrLTqsozripQg64uk7J207JWE66qs65Oc7J2YIOqwgOqyqeydhCDqsrDsoJXtlZjripQg6rCA7J6lIOykkeyalO2VnCDsmpTshozsnbTrqbAsIO2SiOyniOydtCDrgq7snYAg64uk7J207JWE66qs65Oc64qUIOuNlCDtgbAg6rK97Zal7J20IOyeiOyKteuLiOuLpC4KCmBgYHtyfQpnZ3Bsb3QoZGlhbW9uZHMsIGFlcyhjYXJhdCwgcHJpY2UpKSArIAogIGdlb21faGV4KGJpbnMgPSA1MCkKYGBgCgotIOyasOumrOuKlCDri6TsnbTslYTrqqzrk5zsnZgg64uk66W4IOyGjeyEseydtCDsupDrn7/snZgg7Zqo6rO866W8IOu2hOumrO2VmOuKlCDrqqjrjbjsnYQg7ZS87YyF7ZWo7Jy866Gc7I2oIOyDgeuMgOyggeyduCDqsIDqsqnsl5Ag7Ja065a76rKMIOyYge2WpeydhCDrr7jsuZjripTsp4Ag7Im96rKMIOyVjCDsiJgg7J6I7Iq164uI64ukLiAKCi0g7ZWY7KeA66eMIOuovOyggCDri6TsnbTslYTrqqzrk5wg642w7J207YSwIOyEuO2KuOulvCDsobDsnpHtlZjsl6wg7J6R7JeF7ZWY6riwIOyJveuPhOuhnSDrkZAg67KIIOyhsOygle2VmOyLreyLnOyYpC4KCi0g7LqQ65+/IOuvuOunjOydmCDri6TsnbTslYTrqqzrk5zsl5Ag7KeR7KSRICjrjbDsnbTthLDsnZggOTkuNyAlKQoKLSDsupDrn78g67CPIOqwgOqyqSDrs4DsiJjrpbwg66Gc6re4IOuzgO2ZmO2VqeuLiOuLpC4KCmBgYHtyfQpkaWFtb25kczIgPC0gZGlhbW9uZHMgJT4lIAogIGZpbHRlcihjYXJhdCA8PSAyLjUpICU+JSAKICBtdXRhdGUobHByaWNlID0gbG9nMihwcmljZSksIGxjYXJhdCA9IGxvZzIoY2FyYXQpKQoKZ2dwbG90KGRpYW1vbmRzMiwgYWVzKGxjYXJhdCwgbHByaWNlKSkgKyAKICBnZW9tX2hleChiaW5zID0gNTApCmBgYAoKLSDroZzqt7gg67OA7ZmY7J2AIO2MqO2EtOydhCDshKDtmJXsnLzroZwg66eM65Ok6rOgIOyEoO2YlSDtjKjthLTsnYQg7IKs7Jqp7ZWY6riwIOyJveq4sCDrlYzrrLjsl5Ag7Yq57Z6IIOycoOyaqe2VqeuLiOuLpC4gCgotIOuLpOydjCDri6jqs4Trpbwg67Cf7JWEIOqwleugrO2VnCDshKDtmJUg7Yyo7YS07J2EIOygnOqxsO2VtCDrtIXsi5zri6QuIOuovOyggCDrqqjrjbjsnYQg7ZS87YyF7ZWY7JesIO2MqO2EtOydhCDrqoXsi5wg7KCB7Jy866GcIOunjOuTreuLiOuLpC4KCmBgYHtyfQptb2RfZGlhbW9uZCA8LSBsbShscHJpY2UgfiBsY2FyYXQsIGRhdGEgPSBkaWFtb25kczIpCgpncmlkIDwtIGRpYW1vbmRzMiAlPiUgCiAgZGF0YV9ncmlkKGNhcmF0ID0gc2VxX3JhbmdlKGNhcmF0LCAyMCkpICU+JSAKICBtdXRhdGUobGNhcmF0ID0gbG9nMihjYXJhdCkpICU+JSAKICBhZGRfcHJlZGljdGlvbnMobW9kX2RpYW1vbmQsICJscHJpY2UiKSAlPiUgCiAgbXV0YXRlKHByaWNlID0gMiBeIGxwcmljZSkKCmdncGxvdChkaWFtb25kczIsIGFlcyhjYXJhdCwgcHJpY2UpKSArIAogIGdlb21faGV4KGJpbnMgPSA1MCkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IGdyaWQsIGNvbG91ciA9ICJyZWQiLCBzaXplID0gMSkKYGBgCgotIOuLpOydjCDrqqjrjbjsnbQg642w7J207YSw7JeQIOuMgO2VtCDslYzroKTso7zripQg6rKD7J2EIOu0heuLiOuLpC4g66Gc6re4IOuzgO2ZmOydhCDsi6Ttlokg7Leo7IaM7ZWY7JesIOyYiOy4oeydhCDsl63snLzroZwg67OA7ZmY7ZWY66+A66GcIOybkOyLnCDrjbDsnbTthLDsl5Ag7JiI7Lih7J2EIOyYpOuyhOugiOydtCDtlaAg7IiYIOyeiOyKteuLiOuLpC4KCi0g7Jqw66asIOuNsOydtO2EsOyXkCDrjIDtlbQg7Z2l66+466Gc7Jq0IOqyg+ydhCDslYzroKTspI3ri4jri6QuIOuqqOuNuOydhCDrr7/ripTri6TrqbQg7YGwIOuLpOydtOyVhOuqrOuTnOuKlCDsmIjsg4Hrs7Tri6Qg7Zuo7JSsIOyggOugtO2VqeuLiOuLpC4gCgotIOydtOqyg+ydgCDslYTrp4jrj4Qg7J20IOuNsOydtO2EsCDshLjtirjsnZgg64uk7J207JWE66qs65Oc6rCAIDEg66eMIDkg7LKcIOuLrOufrOqwgCDrk6Tsp4Ag7JWK6riwIOuVjOusuOydvCDqsoPsnoXri4jri6QuCgotIOydtOygnCDsmrDrpqzripQg6rCV7ZWcIOyEoO2YlSDtjKjthLTsnYQg7ISx6rO17KCB7Jy866GcIOygnOqxsO2WiOuKlOyngCDtmZXsnbjtlZjripQg7J6U7LCo66W8IOuzvCDsiJgg7J6I7Iq164uI64ukLgoKYGBge3J9CmRpYW1vbmRzMiA8LSBkaWFtb25kczIgJT4lIAogIGFkZF9yZXNpZHVhbHMobW9kX2RpYW1vbmQsICJscmVzaWQiKQoKZ2dwbG90KGRpYW1vbmRzMiwgYWVzKGxjYXJhdCwgbHJlc2lkKSkgKyAKICBnZW9tX2hleChiaW5zID0gNTApCmBgYAoKLSDspJHsmpTtlZwg6rKD7J2AIOydtOygnCDqsIDqsqkg64yA7IugIOyelOywqOulvCDsgqzsmqntlZjsl6wgbW90aXZhdGluZyBwbG90c+ydhCDri6Tsi5wg7ZWgIOyImCDsnojri6TripQg6rKD7J6F64uI64ukLgoKYGBge3J9CmdncGxvdChkaWFtb25kczIsIGFlcyhjdXQsIGxyZXNpZCkpICsgZ2VvbV9ib3hwbG90KCkKZ2dwbG90KGRpYW1vbmRzMiwgYWVzKGNvbG9yLCBscmVzaWQpKSArIGdlb21fYm94cGxvdCgpCmdncGxvdChkaWFtb25kczIsIGFlcyhjbGFyaXR5LCBscmVzaWQpKSArIGdlb21fYm94cGxvdCgpCmBgYAoKLSDsmrDrpqzripQg7Jqw66as6rCAIOq4sOuMgO2VmOuKlCDqtIDqs4Trpbwg67SF64uI64ukIDog64uk7J207JWE66qs65Oc7J2YIO2SiOyniOydtCDrhpLslYTsp4jsiJjroZ0g7IOB64yA7KCB7J24IOqwgOqyqeuPhCDrhpLslYTsp5Hri4jri6QuIAoKLSB5IOy2leydhCDtlbTshJ3tlZjquLAg7JyE7ZW0LCDsmrDrpqzripQg7J6U7LCo6rCAIOyasOumrOyXkOqyjCDrp5DtlZjripQg6rKD6rO8IOq3uOqyg+uTpOydtCDslrTrlqQg7Iqk7LyA7J287J247KeAIOyDneqwge2VoCDtlYTsmpTqsIDsnojri6QuIAoKIyMjIDI0LjIuMiBBIG1vcmUgY29tcGxpY2F0ZWQgbW9kZWwKCi0g7JuQ7ZWc64uk66m0IOuqqOuNuOydhCDqs4Tsho0g6rWs7LaV7ZWY7JesIOq0gOywsOuQnCDtmqjqs7zrpbwg66qo642466GcIOydtOuPmeyLnOy8nCDrqqjrjbjsnYQg66qF7IucIOyggeycvOuhnCDrp4zrk6Qg7IiYIOyeiOyKteuLiOuLpC4gCgotIOyYiOulvCDrk6TslrQg66qo64247JeQIOyDieyDgSwg7Lu3IOuwjyDshKDrqoXrj4Trpbwg7Y+s7ZWo7Iuc7LycIOydtOufrO2VnCAzIOqwgOyngCDrspTso7wg7ZiVIOuzgOyImOydmCDtmqjqs7zrpbwg66qF7IucIO2VoCDsiJgg7J6I7Iq164uI64ukLgoKYGBge3J9Cm1vZF9kaWFtb25kMiA8LSBsbShscHJpY2UgfiBsY2FyYXQgKyBjb2xvciArIGN1dCArIGNsYXJpdHksIGRhdGEgPSBkaWFtb25kczIpCmBgYAoKLSDsnbQg66qo64247JeQ64qUIOydtOygnCA0IOqwnOydmCDsmIjsuKEg67OA7IiY6rCAIO2PrO2VqOuQmOuvgOuhnCDsi5zqsIHtmZTtlZjripQg6rKD7J20IOyWtOugpOybjOynkeuLiOuLpC4gCi0g64uk7ZaJ7Z6I64+ELCDqt7jrk6TsnYAg7ZiE7J6sIOuqqOuRkCDrj4Xrpr3rkJjslrQg7J6I7Ja0IDQg6rCc7J2YIO2UjOuhr+ycvOuhnCDqsJzrs4TsoIHsnLzroZwg6re466a0IOyImCDsnojsirXri4jri6QuIAoKLSDtlITroZzshLjsiqTrpbwg7KKA642UIOyJveqyjO2VmOq4sCDsnITtlbQsIOyasOumrOuKlCBkYXRhX2dyaWTsl5AgLm1vZGVsIOyduOyekOulvCDsgqzsmqntlaAg6rKD7J6F64uI64ukIApgYGB7cn0KZ3JpZCA8LSBkaWFtb25kczIgJT4lIAogIGRhdGFfZ3JpZChjdXQsIC5tb2RlbCA9IG1vZF9kaWFtb25kMikgJT4lIAogIGFkZF9wcmVkaWN0aW9ucyhtb2RfZGlhbW9uZDIpCmdyaWQKCmdncGxvdChncmlkLCBhZXMoY3V0LCBwcmVkKSkgKyAKICBnZW9tX3BvaW50KCkKYGBgCgotIOuqqOuNuOyXkCDrqoXsi5zsoIHsnLzroZwg7KCc6rO17ZWY7KeAIOyViuydgCDrs4DsiJjqsIAg7ZWE7JqU7ZWcIOqyveyasCBkYXRhX2dyaWQgKCnripQg7J6Q64+Z7Jy866GcIOydtOulvCAi7J2867CYIuqwkuycvOuhnCDssYQg7JuB64uI64ukLiAKCi0g7Jew7IaNIOuzgOyImOydmCDqsr3smrAg7KSR7JWZ6rCS7J2EIOyCrOyaqe2VmOqzoCDrspTso7ztmJUg67OA7IiY64qUIOqwgOyepSDsnbzrsJjsoIHsnbgg6rCS7J2EIOyCrOyaqe2VqeuLiOuLpC4KCmBgYHtyfQpkaWFtb25kczIgPC0gZGlhbW9uZHMyICU+JSAKICBhZGRfcmVzaWR1YWxzKG1vZF9kaWFtb25kMiwgImxyZXNpZDIiKQoKZ2dwbG90KGRpYW1vbmRzMiwgYWVzKGxjYXJhdCwgbHJlc2lkMikpICsgCiAgZ2VvbV9oZXgoYmlucyA9IDUwKQpgYGAKCi0g7J20IOq3uOuemO2UhOuKlCDsg4Hri7ntnogg7YGwIOyelOywqOqwgOyeiOuKlCDsnbzrtoAg64uk7J207JWE66qs65Oc6rCAIOyeiOydjOydhCDrgpjtg4Drg4Xri4jri6QuIAoKLSDsnpTssKggMuuKlCDri6TsnbTslYTrqqzrk5zqsIAg7JiI7IOB7ZaI642YIOqwgOqyqeydmCA067Cw652864qUIOqyg+ydhCDrgpjtg4Drg4Xri4jri6QuIAoKLSDruYTsoJXsg4HsoIHsnbgg6rCS7J2EIOqwnOuzhOyggeycvOuhnCDrs7TripQg6rKD7J20IOyiheyihSDsnKDsmqntlanri4jri6QuCgpgYGB7cn0KZGlhbW9uZHMyICU+JSAKICBmaWx0ZXIoYWJzKGxyZXNpZDIpID4gMSkgJT4lIAogIGFkZF9wcmVkaWN0aW9ucyhtb2RfZGlhbW9uZDIpICU+JSAKICBtdXRhdGUocHJlZCA9IHJvdW5kKDIgXiBwcmVkKSkgJT4lIAogIHNlbGVjdChwcmljZSwgcHJlZCwgY2FyYXQ6dGFibGUsIHg6eikgJT4lIAogIGFycmFuZ2UocHJpY2UpCmBgYAoKLSDsl6zquLDsl5Ag64KY7JmAIOyeiOuKlCDqsoPsnYAg7JeG7KeA66eMLCDsnbTqsoPsnbQg66qo64247JeQIOusuOygnOqwgCDsnojripTsp4Ag65iQ64qUIOuNsOydtO2EsOyXkCDsmKTrpZjqsIAg7J6I64qU7KeA66W8IOqzoOugpO2VtCDrs7wg65WMIOyLnOqwhOydhCDtlaAg6rCA7LmY6rCAIOyeiOyKteuLiOuLpC4gCgotIOuNsOydtO2EsOyXkCDsi6TsiJjqsIAg7J6I64qUIOqyveyasCDsnbTripQg7J6Y66q7IOuCruydgCDqsIDqsqnsnLzroZwg7LGF7KCVIOuQnCDri6TsnbTslYTrqqzrk5zrpbwg6rWs66ek7ZWgIOyImOyeiOuKlCDquLDtmozqsIAg65CgIOyImCDsnojsirXri4jri6QuCgoKIyMjIDI0LjIuMyBFeGVyY2lzZXMgKOyDneuetSkKCiMjIyAyNC4zIFdoYXQgYWZmZWN0cyB0aGUgbnVtYmVyIG9mIGRhaWx5IGZsaWdodHM/CgotIOyWuOucuyDrs7TquLDsl5AgTllD66W8IOuWoOuCmOuKlCDtla3qs7XtjrjsnZgg7IiY67O064ukIO2bqOyUrCDri6jsiJztlZwg642w7J207YSwIOyEuO2KuOyXkCDrjIDtlbTshJzrj4Qg7Jyg7IKs7ZWcIO2UhOuhnOyEuOyKpOulvCDsp4TtlontlbQg67O06rKg7Iq164uI64ukLiAKLSDsnbQg66qo64247J2AIDM2NSDqsJzsnZgg7ZaJ6rO8IDIg6rCc7J2YIOyXtOunjOyeiOuKlCDslYTso7wg7J6R7J2AIOuNsOydtO2EsCDshLjtirjsnoXri4jri6QuIOyZhOyghO2eiCDsi6TtmITrkJwg66qo642466GcIOuBneuCmOyngOuKlCDslYrsnYQg6rKD7J6F64uI64ukLgoKLSDtlZjsp4Drp4wg7JWMIOyImCDsnojrk6/snbQg7J20IOuLqOqzhOuKlCDrjbDsnbTthLDrpbwg642UIOyemCDsnbTtlbTtlZjripQg642wIOuPhOybgOydtOuQqeuLiOuLpC4g7ZWY66Oo7JeQIOu5hO2WiSDsiJjrpbwg6rOE7IKw7ZWY6rOgIGdncGxvdDLroZwg7Iuc6rCB7ZmUIO2VtCDrtIXsi5zri6QuCgpgYGB7cn0KbGlicmFyeShueWNmbGlnaHRzMTMpCmxpYnJhcnkobHVicmlkYXRlKQpkYXRhKGZsaWdodHMpCmRhaWx5IDwtIGZsaWdodHMgJT4lIAogIG11dGF0ZShkYXRlID0gbWFrZV9kYXRlKHllYXIsIG1vbnRoLCBkYXkpKSAlPiUgCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lIAogIHN1bW1hcmlzZShuID0gbigpKQpkYWlseQoKZ2dwbG90KGRhaWx5LCBhZXMoZGF0ZSwgbikpICsgCiAgZ2VvbV9saW5lKCkKYGBgCgojIyMgMjQuMy4xIERheSBvZiB3ZWVrCgotIOyepeq4sCDqsr3tlqXsnYQg7J207ZW07ZWY64qUIOqyg+ydgCDslrTroKTsmrQg7J287J6F64uI64ukLiAKCi0g6re4IOydtOycoOuKlCDrr7jrrJjtlZwg7Yyo7YS07J2EIOyngOuwsO2VmOuKlCDrp6TsmrAg6rCV7ZWcIOyalOydvCDtmqjqs7zqsIAg7J6I6riwIOuVjOusuOyeheuLiOuLpC4g7JqU7J2867OEIO2Vreqzte2OuCDrsojtmLgg67aE7Y+s66W8IOyCtO2OtCDrs7TqsqDsirXri4jri6QuCgpgYGB7cn0KZGFpbHkgPC0gZGFpbHkgJT4lIAogIG11dGF0ZSh3ZGF5ID0gd2RheShkYXRlLCBsYWJlbCA9IFRSVUUpKQpnZ3Bsb3QoZGFpbHksIGFlcyh3ZGF5LCBuKSkgKyAKICBnZW9tX2JveHBsb3QoKQpgYGAKCi0g64yA67aA67aE7J2YIOyXrO2WieydgCDruYTspojri4jsiqTrpbwg7JyE7ZWcIOqyg+ydtOuvgOuhnCDso7zrp5Ag7ZWt6rO17Y64IOyImOqwgCDsoIHsirXri4jri6QuIOq3uCDtmqjqs7zripQg7Yag7JqU7J287JeQIO2Kue2eiCDrkZDrk5zrn6zsp4Dqsowg64KY7YOA64Kp64uI64ukLiAKCi0g7JuU7JqU7J28IOyVhOy5qCDrqqjsnoTsnYQg7JyE7ZW0IOydvOyalOydvOyXkCDrlqDrgpjripQg6rK97Jqw64+EIOyeiOyngOunjCwg7Yag7JqU7J287JeQIOqwgOyhseqzvCDtlajqu5gg7KeR7JeQ7J6I64qUIOqyg+yymOufvCDrlqDrgpjripQg6rKD7J2AIOunpOyasCDrk5zrrYXri4jri6QuCgotIOydtCDqsJXroKXtlZwg7Yyo7YS07J2EIOygnOqxsO2VmOuKlCDtlZwg6rCA7KeAIOuwqeuyleydgCDrqqjrjbjsnYQg7IKs7Jqp7ZWY64qUIOqyg+yeheuLiOuLpC4g66i87KCAIOuqqOuNuOydhCDrp57stpTqs6Ag7JuQ67O4IOuNsOydtO2EsOyXkCDsmIjsuKHsuZjrpbwg6rK57LOQ7IScIO2RnOyLnO2VqeuLiOuLpC4KCmBgYHtyfQptb2QgPC0gbG0obiB+IHdkYXksIGRhdGEgPSBkYWlseSkKCmdyaWQgPC0gZGFpbHkgJT4lIAogIGRhdGFfZ3JpZCh3ZGF5KSAlPiUgCiAgYWRkX3ByZWRpY3Rpb25zKG1vZCwgIm4iKQoKZ2dwbG90KGRhaWx5LCBhZXMod2RheSwgbikpICsgCiAgZ2VvbV9ib3hwbG90KCkgKwogIGdlb21fcG9pbnQoZGF0YSA9IGdyaWQsIGNvbG91ciA9ICJyZWQiLCBzaXplID0gNCkKYGBgCgpgYGB7cn0KZGFpbHkgPC0gZGFpbHkgJT4lIAogIGFkZF9yZXNpZHVhbHMobW9kKQpkYWlseSAlPiUgCiAgZ2dwbG90KGFlcyhkYXRlLCByZXNpZCkpICsgCiAgZ2VvbV9yZWZfbGluZShoID0gMCkgKyAKICBnZW9tX2xpbmUoKQpgYGAKCi0geSDstpXsnZgg67OA7ZmU7JeQIOyjvOuqqe2VmOyLreyLnOyYpC4g7J207KCcIOyalOydvOyXkCDsmIjsg4HrkJjripQg67mE7ZaJIO2an+yImOyZgOydmCDtjrjssKjqsIAg7ZGc7Iuc65Cp64uI64ukLiAKCi0g7J20IO2UjOuhr+ydgCDrp47snYAg7JqU7J28IO2aqOqzvOulvCDsoJzqsbAg7ZaI7Jy866+A66GcIOuCqOyVhOyeiOuKlCDrjZQg7ISs7IS47ZWcIO2MqO2EtOydhCDrs7wg7IiYIOyeiOq4sCDrlYzrrLjsl5Ag7Jyg7Jqp7ZWp64uI64ukLgoKLSDsmrDrpqwg66qo64247J2AIDbsm5TrtoDthLAg7Iuk7YyoIO2VoCDqsoPsnLzroZwg67O07J6F64uI64ukLiDsmrDrpqwg66qo64247J20IO2PrOywqe2VmOyngCDslYrsnYAg6rCV66Cl7ZWcIOq3nOy5meyggeyduCDtjKjthLTsnYQg7Jes7KCE7Z6IIOuzvCDsiJgg7J6I7Iq164uI64ukLiDrp6Tso7wg7ZWcIOykhOyUqSDspITsnYQg6re466as66m0IOq3uCDsm5DsnbjsnYQg7Im96rKMIOyVjCDsiJgg7J6I7Iq164uI64ukLgoKYGBge3J9CmdncGxvdChkYWlseSwgYWVzKGRhdGUsIHJlc2lkLCBjb2xvdXIgPSB3ZGF5KSkgKyAKICBnZW9tX3JlZl9saW5lKGggPSAwKSArIAogIGdlb21fbGluZSgpCmBgYAoKLSDsmrDrpqwg66qo64247J2AIO2GoOyalOydvOyXkCDruYTtlokg7Zqf7IiY66W8IOygle2Zle2eiCDsmIjsuKHtlZjsp4Ag66q77ZWp64uI64ukLgoKLSDsl6zrpoTsl5DripQg7JiI7IOB67O064ukIOunjuydgCDtla3qs7XtjrjsnbQg7J6I6rOgLCDqsIDsnYTsl5DripQg642UIOyggeydgCDtla3qs7XtjrjsnbQg7J6I7Iq164uI64ukLiDri6TsnYwg7IS57IWY7JeQ7ISc7J20IO2MqO2EtOydhCDsuqHsspjtlZjripQg67Cp67KV7J2EIOuNlCDsnpgg7J207ZW07ZWgIOyImCDsnojsirXri4jri6QuCgotIOyYiOyDgeuztOuLpCDtm6jslKwg7KCB7J2AIO2Vreqzte2OuOycvOuhnCDsiJgg7J287J20IOyeiOyKteuLiOuLpC4KCmBgYHtyfQpkYWlseSAlPiUgCiAgZmlsdGVyKHJlc2lkIDwgLTEwMCkKYGBgCgotIOuvuOq1reydmCDqs7XtnLTsnbzsl5Ag7J217IiZ7ZWY64uk66m0IDcg7JuUIDQg7J28LCDstpTsiJgg6rCQ7IKs7KCI6rO8IO2BrOumrOyKpOuniOyKpOulvCDrs7wg7IiYIOyeiOyKteuLiOuLpC4gCgotIOqzte2ctOydvOqzvCDsnbzsuZjtlZjsp4Ag7JWK64qUIOqygyDrqocg6rCA7KeA6rCAIOyeiOyKteuLiOuLpC4g7Jew7Iq1IOusuOygnCDspJEg7ZWY64KY7JeQ7IScIOyekeyXhSDtlaAg6rKD7J6F64uI64ukLgoKLSAxIOuFhCDrj5nslYgg7J6l6riw6rCE7JeQIOqxuOyzkOuztOuLpCDrp6TrgYTrn6zsmrQg7LaU7IS46rCAIOuCmO2DgOuCqeuLiOuLpC4gZ2VvbV9zbW9vdGggKCnrpbwg7IKs7Jqp7ZWY7JesIOydtOufrO2VnCDstpTshLjrpbwg6rCV7KGwIO2VoCDsiJgg7J6I7Iq164uI64ukLgoKYGBge3J9CmRhaWx5ICU+JSAKICBnZ3Bsb3QoYWVzKGRhdGUsIHJlc2lkKSkgKyAKICBnZW9tX3JlZl9saW5lKGggPSAwKSArIAogIGdlb21fbGluZShjb2xvdXIgPSAiZ3JleTUwIikgKyAKICBnZW9tX3Ntb290aChzZSA9IEZBTFNFLCBzcGFuID0gMC4yMCkKCmBgYAoKLSAxIOyblCAoMTIg7JuUIOyXkOuKlCDtla3qs7XtjrjsnbQg642UIOyggeqzoCDsl6zrpoQgKDUg7JuUIC05IOyblCnsl5DripQg642UIOunjuydgCDtla3qs7XtjrjsnbQg7J6I7Iq164uI64ukLiAKCi0g7Jqw66as64qUIOuLqOyngCAxIOuFhOydmCDrjbDsnbTthLAg66eMIOqwgOyngOqzoCDsnojquLAg65WM66y47JeQ7J20IO2MqO2EtOydhCDsoJXrn4nsoIHsnLzroZwg66eO7J20IO2VoCDsiJgg7JeG7Iq164uI64ukLiDqt7jrn6zrgpgg7Jqw66as64qUIOuPhOuplOyduCDsp4Dsi53snYQg7IKs7Jqp7ZWY7JesIOyeoOyerOyggSDshKTrqoXsnYQg67iM66CI7J24IOyKpO2GoOuwjSDtlaAg7IiYIOyeiOyKteuLiOuLpC4KCiMjIyAyNC4zLjIgU2Vhc29uYWwgU2F0dXJkYXkgZWZmZWN0CgotIOuovOyggCDthqDsmpTsnbzsl5Ag67mE7ZaJIO2an+yImOulvCDsoJXtmZXtlZjqsowg7JiI7Lih7ZWY7KeAIOuqu+2VmOqyjCDtlZjsi63si5zsmKQuIOyLnOyeke2VmOq4sCDsoovsnYAg6rOz7J2AIO2GoOyalOydvOyXkCDstIjsoJDsnYQg66ee7LaU7Ja0IOybkOyLnCDrsojtmLjroZwg64+M7JWE6rCA64qUIOqyg+yeheuLiOuLpC4KCmBgYHtyfQpkYWlseSAlPiUgCiAgZmlsdGVyKHdkYXkgPT0gIlNhdCIpICU+JSAKICBnZ3Bsb3QoYWVzKGRhdGUsIG4pKSArIAogICAgZ2VvbV9wb2ludCgpICsgCiAgICBnZW9tX2xpbmUoKSArCiAgICBzY2FsZV94X2RhdGUoTlVMTCwgZGF0ZV9icmVha3MgPSAiMSBtb250aCIsIGRhdGVfbGFiZWxzID0gIiViIikKYGBgCgotICjrjbDsnbTthLDsmYAg67O06rCE7J20IOustOyXh+yduOyngCDrqoXtmZXtlZjqsowg7ZWY6riwIOychO2VtCDsoJDqs7wg7ISg7J2EIOuqqOuRkCDsgqzsmqntlojsirXri4jri6QuKQoKLSDrgpjripQg7J20IO2MqO2EtOydtCDsl6zrpoQg7Zy06rCA66GcIOyduO2VtCDsnbzslrTrgpzri6Tqs6Ag7IOd6rCB7ZWp64uI64ukIDog66eO7J2AIOyCrOuejOuTpOydtCDsl6zrpoTsl5Ag7Zy06rCA66W8IOqwgOyngOupsCDsgqzrnozrk6TsnYAg7Zy06rCA66W8IOychO2VtCDthqDsmpTsnbwg7Jes7ZaJ7J2EIOq6vOugpO2VmOyngCDslYrsirXri4jri6QuIAoKLSDsnbQg7J2M66qo66W8IOuztOuptCDsl6zrpoQg7Zy06rCA6rCAIDYg7JuUIOy0iOyXkOyEnCA4IOyblCDrp5DquYzsp4Drnbzqs6Ag7LaU7LihIO2VoCDsiJgg7J6I7Iq164uI64ukLiAyMDEzIOuFhCDsl6zrpoQg67Cp7ZWZ7J2AIDYg7JuUIDI2LTkg7JuUIDkg7J287J207JeI7Iq164uI64ukLgoKLSDrtITsl5Ag6rCA7J2E67O064ukIOqwgOydhOyXkCDthqDsmpTsnbwg67mE7ZaJ7J20IOuNlCDrp47snYAg7J207Jyg64qUIOustOyXh+yeheuLiOq5jD8g64KY64qUIOuvuOq1reyduCDsuZzqtazrk6Tsl5Dqsowg66y87JeI6rOgIOy2lOyImCDqsJDsgqzsoIjqs7wg7YGs66as7Iqk66eI7IqkIO2ctOqwgCDrlYzrrLjsl5Ag6rCA7J2EIOuPmeyViCDqsIDsobEg7Zy06rCA66W8IOqzhO2aje2VmOuKlCDqsoPsnbQg642cIOydvOuwmOyggeydtOudvOqzoCDsoJzslYjtlojri6QuIOyasOumrOuKlCDtmZXsi6Ttnogg7JWMIOyImOyeiOuKlCDrjbDsnbTthLDqsIAg7JeG7KeA66eMIOq3uOuftOuTr+2VnCDsnpHsl4Ug6rCA7ISk7LKY65+8IOuztOyeheuLiOuLpC4KCi0g64yA6561IOyEuCDqsIDsp4Ag7Jqp7Ja066W8IO2PrOywqe2VmOuKlCAidGVybSIg67OA7IiY66W8IOunjOuTpOqzoCwg7Jqw66as7J2YIOyekeyXheydhCDsnYzrqqjroZwg7ZmV7J247ZWY7Iut7Iuc7JikLgoKYGBge3J9CnRlcm0gPC0gZnVuY3Rpb24oZGF0ZSkgewogIGN1dChkYXRlLCAKICAgIGJyZWFrcyA9IHltZCgyMDEzMDEwMSwgMjAxMzA2MDUsIDIwMTMwODI1LCAyMDE0MDEwMSksCiAgICBsYWJlbHMgPSBjKCJzcHJpbmciLCAic3VtbWVyIiwgImZhbGwiKSAKICApCn0KCmRhaWx5IDwtIGRhaWx5ICU+JSAKICBtdXRhdGUodGVybSA9IHRlcm0oZGF0ZSkpIAoKZGFpbHkgJT4lIAogIGZpbHRlcih3ZGF5ID09ICJTYXQiKSAlPiUgCiAgZ2dwbG90KGFlcyhkYXRlLCBuLCBjb2xvdXIgPSB0ZXJtKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAxLzMpICsgCiAgZ2VvbV9saW5lKCkgKwogIHNjYWxlX3hfZGF0ZShOVUxMLCBkYXRlX2JyZWFrcyA9ICIxIG1vbnRoIiwgZGF0ZV9sYWJlbHMgPSAiJWIiKQpgYGAKCi0gKOuCmOuKlCDtlIzroa/sl5DshJwg7KKL7J2AIO2ctOyLneydhCDst6jtlZjquLAg7JyE7ZW0IOyImOuPmeycvOuhnCDrgqDsp5zrpbwg7KGw7KCV7ZaI64ukLiDsi5zqsIHtmZTrpbwg7IKs7Jqp7ZWY7JesIO2VqOyImOqwgO2VmOuKlCDsnbzsnYQg7J207ZW07ZWY64qUIOuNsCDrj4Tsm4DsnbTrkJjripQg6rKD7J2AIOygleunkCDqsJXroKXtlZjqs6Ag7J2867CY7KCB7J24IOq4sOyIoOydtOuLpC4pCgotIOydtCDsg4jroZzsmrQg67OA7IiY6rCAIOuLpOuluCDsmpTsnbzsl5Ag7Ja065akIOyYge2WpeydhCDso7zripTsp4Ag7ZmV7J247ZWY64qUIOqyg+ydtCDsnKDsmqntlanri4jri6QuCgpgYGB7cn0KZGFpbHkgJT4lIAogIGdncGxvdChhZXMod2RheSwgbiwgY29sb3VyID0gdGVybSkpICsKICAgIGdlb21fYm94cGxvdCgpCmBgYAoKLSDsmqnslrQg7KCE67CY7JeQIOqxuOyzkCDtgbAg67OA64+Z7J20IOyeiOuKlCDqsoPsspjrn7wg67O07J2066+A66GcIOqwgSDsmqnslrTsl5Ag64yA7ZW0IOyalOydvOuzhCDtmqjqs7zrpbwg7KCB7Jqp7ZWY64qUIOqyg+ydtCDtlanrpqzsoIHsnoXri4jri6QuIAoKLSDsnbTqsoPsnYAg7Jqw66as7J2YIOuqqOuNuOydhCDtlqXsg4Eg7Iuc7YKk7KeA66eMLCDsmrDrpqzqsIAg67CU652864qUIOqyg+unjCDtgbzsnYAg7JWE64uZ64uI64ukLgoKYGBge3J9CmRhaWx5IDwtIGRhaWx5ICU+JSAKICBtdXRhdGUodGVybSA9IHRlcm0oZGF0ZSkpIAoKbW9kMSA8LSBsbShuIH4gd2RheSwgZGF0YSA9IGRhaWx5KQptb2QyIDwtIGxtKG4gfiB3ZGF5ICogdGVybSwgZGF0YSA9IGRhaWx5KQoKZGFpbHkgJT4lIAogIGdhdGhlcl9yZXNpZHVhbHMod2l0aG91dF90ZXJtID0gbW9kMSwgd2l0aF90ZXJtID0gbW9kMikgJT4lIAogIGdncGxvdChhZXMoZGF0ZSwgcmVzaWQsIGNvbG91ciA9IG1vZGVsKSkgKwogICAgZ2VvbV9saW5lKGFscGhhID0gMC43NSkKYGBgCgotIOuqqOuNuOydmCDsmIjsuKHsnYQg7JuQ7IucIOuNsOydtO2EsOyXkCDqsrnss5DshJwg66y47KCc66W8IOuzvCDsiJgg7J6I7Iq164uI64ukLgoKYGBge3J9CmdyaWQgPC0gZGFpbHkgJT4lIAogIGRhdGFfZ3JpZCh3ZGF5LCB0ZXJtKSAlPiUgCiAgYWRkX3ByZWRpY3Rpb25zKG1vZDIsICJuIikKCmdncGxvdChkYWlseSwgYWVzKHdkYXksIG4pKSArCiAgZ2VvbV9ib3hwbG90KCkgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBncmlkLCBjb2xvdXIgPSAicmVkIikgKyAKICBmYWNldF93cmFwKH4gdGVybSkKYGBgCgotIOyasOumrOydmCDrqqjrjbjsnYAg7Y+J6regIO2aqOqzvOulvCDssL7ripQg6rKD7J207KeA66eMIOyasOumrOuKlCDtgbAg7J207IOBIOy5mOulvCDrp47snbQg6rCA7KeA6rOgIOyeiOycvOuvgOuhnCDtj4nqt6DsnYAg7KCE7ZiV7KCB7J24IOqwkuyXkOyEnCDrqYDrpqwg65ao7Ja07KeA64qUIOqyve2WpeydtCDsnojsirXri4jri6QuIAoKLSBybG0gKCnsnYQg7IKs7Jqp7ZWY66m0IOydtCDrrLjsoJzrpbwg7ZW06rKw7ZWgIOyImCDsnojsirXri4jri6QuIOydtOqyg+ydgCBvdXRsaWVyc+ydmCDstpTsoJXsuZjsl5Ag64yA7ZWcIOyYge2WpeydhCDtgazqsowg7KSE7J206rOgIOyalOydvCDtjKjthLTsnYQg7KCc6rGw7ZWY64qUIO2bjOulre2VnCDsnpHsl4XsnYQg7IiY7ZaJ7ZWY64qUIOuqqOuNuOydhCDsoJzqs7Xtlanri4jri6QuCgpgYGB7cn0KbW9kMyA8LSBNQVNTOjpybG0obiB+IHdkYXkgKiB0ZXJtLCBkYXRhID0gZGFpbHkpCgpkYWlseSAlPiUgCiAgYWRkX3Jlc2lkdWFscyhtb2QzLCAicmVzaWQiKSAlPiUgCiAgZ2dwbG90KGFlcyhkYXRlLCByZXNpZCkpICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgc2l6ZSA9IDIsIGNvbG91ciA9ICJ3aGl0ZSIpICsgCiAgZ2VvbV9saW5lKCkKYGBgCgotIOyepeq4sOyggeyduCDstpTshLjsmYAg6riN7KCV7KCB7J24IOqyg+qzvCDrtoDsoJXsoIHsnbgg7J207IOB7LmY66W8IOuztOuKlCDqsoPsnbQg7Zuo7JSsIOyJrOybjOyhjOyKteuLiOuLpC4KCiMjIyAyNC4zLjMgQ29tcHV0ZWQgdmFyaWFibGVzCgotIOunjuydgCDrqqjrjbjqs7wg66eO7J2AIOyLnOqwge2ZlOulvCDsi6Ttl5jtlZjqs6Ag7J6I64uk66m0IOuzgOyImCDsg53shLHsnYQgCgotIO2VmOuCmOydmCDtlajsiJjroZwg66y27Ja0IOyEnOuhnCDri6Trpbgg67OA7ZmY7J2EIOyasOyXsO2eiCDsoIHsmqkg7ZWgIOq4sO2ajOqwgOyXhuuKlCDqsoPsnbQg7KKL7Iq164uI64ukLiDsmIjrpbwg65Ok7Ja0IOuLpOydjOqzvCDqsJnsnbQg7JO4IOyImCDsnojsirXri4jri6QuCgpgYGB7cn0KY29tcHV0ZV92YXJzIDwtIGZ1bmN0aW9uKGRhdGEpIHsKICBkYXRhICU+JSAKICAgIG11dGF0ZSgKICAgICAgdGVybSA9IHRlcm0oZGF0ZSksIAogICAgICB3ZGF5ID0gd2RheShkYXRlLCBsYWJlbCA9IFRSVUUpCiAgICApCn0KYGBgCgotIOuYkCDri6Trpbgg7Ji17IWY7J2AIOuzgO2ZmOydhCDrqqjrjbgg7IiY7Iud7JeQIOyngeygkSDrhKPripQg6rKD7J6F64uI64ukLgoKYGBge3J9CndkYXkyIDwtIGZ1bmN0aW9uKHgpIHdkYXkoeCwgbGFiZWwgPSBUUlVFKQptb2QzIDwtIGxtKG4gfiB3ZGF5MihkYXRlKSAqIHRlcm0oZGF0ZSksIGRhdGEgPSBkYWlseSkKYGBgCgotIOuRkCDrsKnrspUg66qo65GQIO2VqeumrOyggeyduCDrsKnrspXsnoXri4jri6QuIOuzgO2YlSDrkJwg67OA7IiY66W8IOuqheyLnCDsoIHsnLzroZwg66eM65Oc64qUIOqyg+ydgCDsnpHsl4XsnYQg7ZmV7J247ZWY6rGw64KYIOyLnOqwge2ZlOyXkCDsgqzsmqntlZjroKTripQg6rK97JqwIOycoOyaqe2VqeuLiOuLpC4gCgotIOq3uOufrOuCmCDsl6zrn6wg7Je07J2EIOuwmO2ZmO2VmOuKlCDrs4DtmJUgKOyYiCA6IOyKpO2UjOudvOyduCnsnYQg7Im96rKMIOyCrOyaqe2VoCDsiJgg7JeG7Iq164uI64ukLiAKCi0g66qo6424IO2VqOyImOyXkCDrs4DtmJXsnYQg7Y+s7ZWoIOyLnO2CpOuptCDrqqjrjbjsnbQg7J6Q7LK0IO2PrO2VqOuQmOyWtCDsnojquLAg65WM66y47JeQIOunjuydgCDri6Trpbgg642w7J207YSwIOyEuO2KuOuhnCDsnpHsl4Ug7ZWgIOuVjCDsooAg642UIO2OuO2VmOqyjCDsgqzsmqntlaAg7IiYIOyeiOyKteuLiOuLpC4KCgojIyMgMjQuMy40IFRpbWUgb2YgeWVhcjogYW4gYWx0ZXJuYXRpdmUgYXBwcm9hY2gKCi0g7J207KCEIOyEueyFmOyXkOyEnOuKlCDrqqjrjbgg6rCc7ISg7J2EIOychO2VtCDrj4TrqZTsnbgg7KeA7IudICjrr7jqta0g7ZWZ6rWQIOyaqeyWtOqwgCDsl6ztlonsl5Ag66+47LmY64qUIOyYge2WpSnsnYQg7IKs7Jqp7ZaI7Iq164uI64ukLgoKLSDrqqjrjbjsl5DshJwg66qF7IucIOyggeycvOuhnCDsp4Dsi53snYQg7IKs7Jqp7ZWY64qUIOuMgOyLoCDrjbDsnbTthLDsl5Ag642UIOunjuydgCDrjIDtmZQg6rO16rCE7J2EIOygnOqztSDtlaAg7IiYIOyeiOyKteuLiOuLpC4gCgotIOuNlCDsnKDsl7DtlZwg66qo64247J2EIOyCrOyaqe2VmOyXrCDqtIDsi6zsnojripQg7Yyo7YS07J2EIOy6oeyymCDtlaAg7IiYIOyeiOyKteuLiOuLpC4g6rCE64uo7ZWcIOyEoO2YlSDstpTshLjqsIAg7KCB7ZWp7ZWY7KeAIOyViuycvOuvgOuhnCDsnpDsl7DsiqTrn6zsmrQg7Iqk7ZSM65287J247J2EIOyCrOyaqe2VmOyXrCDsnbzrhYQg64K064K0IOunpOuBhOufrOyatCDqs6HshKDsnYQg66eM65OkIOyImCDsnojsirXri4jri6QuCgpgYGB7cn0KbGlicmFyeShzcGxpbmVzKQptb2QgPC0gTUFTUzo6cmxtKG4gfiB3ZGF5ICogbnMoZGF0ZSwgNSksIGRhdGEgPSBkYWlseSkKCmRhaWx5ICU+JSAKICBkYXRhX2dyaWQod2RheSwgZGF0ZSA9IHNlcV9yYW5nZShkYXRlLCBuID0gMTMpKSAlPiUgCiAgYWRkX3ByZWRpY3Rpb25zKG1vZCkgJT4lIAogIGdncGxvdChhZXMoZGF0ZSwgcHJlZCwgY29sb3VyID0gd2RheSkpICsgCiAgICBnZW9tX2xpbmUoKSArCiAgICBnZW9tX3BvaW50KCkKYGBgCgotIOyasOumrOuKlCDthqDsmpTsnbwg67mE7ZaJIO2an+yImOyXkCDqsJXtlZwg7Yyo7YS07J2EIOuztOyVmOyKteuLiOuLpC4g7Jqw66as64qUIOybkOyLnCDrjbDsnbTthLDsl5DshJwg6re4IO2MqO2EtOydhCDrs7TslZjquLAg65WM66y47JeQIOyViOyLrO2VoCDsiJgg7J6I7Iq164uI64ukLiDri6Trpbgg7KCR6re867KV7JeQ7IScIOqwmeydgCDsi6DtmLjrpbwg7Ja77Jy866m0IOyii+ydgCDsi6DtmLjsnoXri4jri6QuCgojIyMgMjQuMy41IEV4ZXJjaXNlcyAo7IOd6561KQoKIyMjIDI0LjQgTGVhcm5pbmcgbW9yZSBhYm91dCBtb2RlbHMKCi0g7Jqw66as64qUIOuqqOuNuOungeydmCDsoIjrjIDsoIHsnbgg66m066eMIOyNvOyngOunjCwg7IKs7Jqp7J6Q6rCAIOyekOyLoOydmCDrjbDsnbTthLAg67aE7ISd7J2EIO2WpeyDgeyLnO2CpOuKlCDrjbAg7IKs7Jqp7ZWgIOyImOyeiOuKlCDri6jsiJztlZjsp4Drp4wg7J2867CY7KCB7J24IOuqqeyggeydmCDrj4Tqtazrpbwg7Ja77JeI6riw66W8IOuwlOuejeuLiOuLpC4g6rCE64uo7ZWY6rKMIOyLnOyeke2VmOuKlCDqsoPsnbQg7KKL7Iq164uI64ukISAKCi0g7J207KCE7JeQIOuztOyVmCDrk6/snbQg66ek7JqwIOuLqOyInO2VnCDrqqjrjbjsobDssKjrj4Qg67OA7IiY6rCE7J2YIOyDge2YuCDsnpHsmqnsnYQg7JWM7JWE64K064qUIOuKpeugpeyXkCDtgbAg7LCo7J2066W8IOunjOuTpCDsiJgg7J6I7Iq164uI64ukLgoKLSDsnbQg66qo642466eBIOyxle2EsOuKlCDrgpjrqLjsp4Ag7LGF67O064ukIO2bqOyUrCDrjZQg64+F7LC97KCB7J6F64uI64ukLiAKCi0g64KY64qUIOuLpOyGjCDri6Trpbgg6rSA7KCQ7JeQ7IScIOuMgOu2gOu2hOydmCDri6Trpbgg6rSA7KCQ7Jy866GcIOuqqOuNuOungeyXkCDsoJHqt7ztlZjrqbAsIOq3uOqyg+yXkCDrjIDtlbQg7IOB64yA7KCB7Jy866GcIOqzteqwhOydtCDqsbDsnZgg7JeG64ukLiDrqqjrjbjrp4HsnYAg7Iuk7KCc66GcIOuPheyekOyggeycvOuhnCDssYXsnYTrsJvsnYQg7J6Q6rKp7J20IOyeiOycvOuvgOuhnCzsnbQg7IS4IOq2jOydmCDssYUg7KSRIOyggeyWtOuPhCDtlZjrgpjrpbwg7J2964qUIOqyg+ydtCDsoovsirXri4jri6QuCgoxLiBTdGF0aXN0aWNhbCBNb2RlbGluZzogQSBGcmVzaCBBcHByb2FjaCBieSBEYW5ueSBLYXBsYW4sIGh0dHA6Ly93d3cubW9zYWljLXdlYi5vcmcvZ28vU3RhdGlzdGljYWxNb2RlbGluZy8uCgoyLiBBbiBJbnRyb2R1Y3Rpb24gdG8gU3RhdGlzdGljYWwgTGVhcm5pbmcgYnkgR2FyZXRoIEphbWVzLCBEYW5pZWxhIFdpdHRlbiwgVHJldm9yIEhhc3RpZSwgYW5kIFJvYmVydCBUaWJzaGlyYW5pLCBodHRwOi8vd3d3LWJjZi51c2MuZWR1L35nYXJldGgvSVNMLyAKCjMuIEFwcGxpZWQgUHJlZGljdGl2ZSBNb2RlbGluZyBieSBNYXggS3VobiBhbmQgS2plbGwgSm9obnNvbiwgaHR0cDovL2FwcGxpZWRwcmVkaWN0aXZlbW9kZWxpbmcuY29tCgojIyAyNS4gTWFueSBtb2RlbHMKCiMjIyAyNS4xIEludHJvZHVjdGlvbgoKLSDsnbQg7J6l7JeQ7ISc64qUIOunjuydgCDsiJjsnZgg66qo64247J2EIOyJveqyjCDsgqzsmqntlaAg7IiYIOyeiOuPhOuhnSDrj4TsmYDso7zripQg7IS4IOqwgOyngCDqsJXroKXtlZwg7JWE7J2065SU7Ja066W8IO2VmeyKte2VqeuLiOuLpC4KCi0g66eO7J2AIOqwhOuLqO2VnCDrqqjrjbjsnYQg7IKs7Jqp7ZWY7JesIOuzteyeoe2VnCDrjbDsnbTthLAg7IS47Yq466W8IOuNlCDsnpgg7J207ZW07ZWp64uI64ukLgoKLSBsaXN0LWNvbHVtbnPrpbwg7IKs7Jqp7ZWY7JesIOyehOydmOydmCDrjbDsnbTthLAg6rWs7KGw66W8IOuNsOydtO2EsCDtlITroIjsnoTsl5Ag7KCA7J6l7ZWp64uI64ukLiDsmIjrpbwg65Ok7Ja0IOyEoO2YlSDrqqjrjbjsnYQg7Y+s7ZWo7ZWY64qUIOyXtOydhCDqsIDsp4gg7IiYIOyeiOyKteuLiOuLpC4KCi0gRGF2aWQgUm9iaW5zb27snZggYnJvb20g7Yyo7YKk7KeA66W8IOyCrOyaqe2VmOyXrCDrqqjrjbjsnYQg6rmU64GU7ZWcIOuNsOydtO2EsOuhnCDrs4DtmZjtlanri4jri6QuIOunjuydgCDslpHsnZgg66qo642466GcIOyekeyXhe2VmOq4sOychO2VnCDqsJXroKXtlZwg6riw7Iig7J6F64uI64ukLiDsnbzri6gg6rmU64GU7ZWcIOuNsOydtO2EsOqwgCDsnojsnLzrqbQg7J207KCE7JeQIOuwsOyatCDrqqjrk6Ag6riw7Iig7J2EIOyggeyaqSDtlaAg7IiYIOyeiOq4sCDrlYzrrLjsnoXri4jri6QuCgotIOyasOumrOuKlCDsoITshLjqs4TsnZgg7Y+J6regIOyImOuqheyXkCDqtIDtlZwg642w7J207YSw66W8IOyCrOyaqe2VmOyXrCDrj5nquLAg67aA7Jes7J2YIOyYiOygnOuhnCDrm7DslrTrk6Qg6rKD7Jy866GcIOyLnOyeke2VqeuLiOuLpC4gCgotIOyekeydgCDrjbDsnbTthLAg7IS47Yq47J207KeA66eMIOyLnOqwge2ZlOulvCDtlqXsg4Hsi5ztgqTripQg642wIOuqqOuNuOungeydtCDslrzrp4jrgpgg7KSR7JqU7ZWc7KeAIOuztOyXrOykjeuLiOuLpC4gCgotIOyasOumrOuKlCDrp47snYAg7IiY7J2YIOqwhOuLqO2VnCDrqqjrjbjsnYQg7IKs7Jqp7ZWY7JesIOqwgOyepSDqsJXroKXtlZwg7Iug7Zi466W8IOu2hO2VoO2VmOyXrCDrgqjslYTsnojripQg642UIOyVve2VnCDsi6DtmLjrpbwg67O8IOyImCDsnojsirXri4jri6QuIAoKLSDrqqjrjbgg7JqU7JW97J2EIO2Gte2VtCDsmrDrpqzqsIAg7Yq57J20IOy5mOyZgCDruYTsoJXsg4HsoIHsnbgg6rK97Zal7J2EIO2MjOyVhe2VmOuKlCDrjbAg64+E7JuA7J2EIOykhCDsiJjsnojripQg67Cp67KV64+EIOyCtO2OtCDrtIXri4jri6QuCgotIOuLpOydjCDshLnshZjsl5DshJzripQg6rCc67OEIOq4sOyIoOyXkCDrjIDtlbQg7J6Q7IS47Z6IIOyEpOuqhe2VqeuLiOuLpC4KCi0g66qp66GdIOyXtCDrjbDsnbTthLAg6rWs7KGwIOuwjyDrjbDsnbTthLAg7ZSE66CI7J6E7JeQIOuqqeuhneydhCDrhKPripQg6rKD7J20IO2DgOuLue2VnCDsnbTsnKDsl5Ag64yA7ZW0IOyekOyEuO2eiCDrsLDsm4Hri4jri6QuCgotIOuqqeuhnSDsl7Qg7J6R7ISx7JeQ7IScIOuqqeuhnSDsl7TsnYQg7J6R7ISx7ZWY64qUIOyEuCDqsIDsp4Ag7KO87JqUIOuwqeuyleydhCDtlZnsirXtlanri4jri6QuCgotIOuqqeuhnSDsl7TsnYQg64uo7Iic7ZmUIO2VoCDrlYwg66qp66GdIOyXtOydhCDsnbzrsJgg7JuQ7J6QIOuyoe2EsCAo65iQ64qUIOybkOyekCDrsqHthLAg7KeR7ZWpKeuhnCDri6Tsi5wg67OA7ZmY7ZWY7Jes67O064ukIOyJveqyjCDsnpHsl4Ug7ZWgIOyImCDsnojrj4TroZ3tlZjripQg67Cp67KV7J2EIOuwsOybgeuLiOuLpC4KCi0gYnJvb23roZwg6rmU64GU7ZWcIOuNsOydtO2EsOulvCDrp4zrk6Qg65WMLCBicm9vbeydtOygnOqzte2VmOuKlCDrqqjrk6Ag64+E6rWsIOyEuO2KuOyXkCDrjIDtlbQg67Cw7Jqw6rOgIOuLpOuluCDsnKDtmJXsnZgg642w7J207YSwIOq1rOyhsOyXkCDslrTrlrvqsowg7KCB7JqpIO2VoCDsiJgg7J6I64qU7KeAIOyCtO2OtCDrtIXri4jri6QuCgotIOydtCDsnqXsnYAg64uk7IaMIO2PrOu2gOqwgCDsnojsirXri4jri6Qu7J20IOyxheydtCBS7JeQIOuMgO2VnCDssqsg67KI7Ke4IOyGjOqwnCDsnbgg6rK97JqwIOydtCDsnqXsnYAg7Ja066Ck7Jq4IOqyg+yeheuLiOuLpC4g66qo642466eBLCDrjbDsnbTthLAg6rWs7KGwIOuwjyDrsJjrs7Xsl5Ag64yA7ZWcIOyVhOydtOuUlOyWtOulvCDquYrsnbQg64K066m07ZmU7ZW07JW87ZWp64uI64ukLiAKCi0g64u57Iug7J20IOq3uOqyg+ydhCDslrvsp4Ag66q77ZWc64uk66m0IOqxseygle2VmOyngCDrp4jsi63si5zsmKQuIOuLqOyngCDrqocg64usIOuPmeyViOydtCDsnqXsnYQg7KCc7LOQ65GQ6rOgIOuouOumrOulvCDtjrTqs6Ag7Iu27J2EIOuVjCDri6Tsi5wg7Jik7Iut7Iuc7JikLgoKIyMjIDI1LjEuMSBQcmVyZXF1aXNpdGVzCgotIOunjuydgCDrqqjrjbjroZwg7J6R7JeF7ZWY64qUIOqyg+ydgCDrqqjrjbjrp4HsnYQg7Jqp7J207ZWY6rKM7ZWY6riwIOychO2VtCB0aWR5dmVyc2UgKOuNsOydtO2EsCDtg5Dsg4ksIOuFvOyfgSDrsI8g7ZSE66Gc6re4656Y67CNKSDrsI8gbW9kZWxyIO2MqO2CpOyngOydmCDrp47snYAg7Yyo7YKk7KeA66W8IO2VhOyalOuhnO2VqeuLiOuLpC4KCmBgYHtyfQpsaWJyYXJ5KG1vZGVscikKbGlicmFyeSh0aWR5dmVyc2UpCmBgYAoKIyMjIDI1LjIgZ2FwbWluZGVyCgotIOunjuydgCDqsITri6jtlZwg66qo64247J2YIO2emOydhCDsnKDrj4TtlZjquLAg7JyE7ZW0ICJnYXBtaW5kZXIi642w7J207YSw66W8IOyCtO2OtOuzvCDqsoPsnoXri4jri6QuIAoKLSDsnbQg642w7J207YSw64qUIOyKpOybqOuNtOydmCDsnZjsgqzsnbTsnpAg7Ya16rOEIO2VmeyekCDsnbggSGFucyBSb3NsaW5n7JeQIOydmO2VtCDrjIDspJHtmZTrkJjsl4jsirXri4jri6QuIOuEiOuKlCDqt7gg7IKs656M7JeQIOuMgO2VtCDrk6TslrQg67O4IOyggeydtCDsl4bri6TrqbQsIOyngOq4iCDri7nsnqXsnbQg7J6l7J2EIOydveyngCDrp5Dqs6Ag6re47J2YIOu5hOuUlOyYpOulvCDrs7TslYTrnbwuIAoKLSDqt7jripQg7ZmY7IOB7KCB7J24IOuNsOydtO2EsCDrsJztkZzsnpDsnbTrqbAg642w7J207YSw66W8IOyCrOyaqe2VmOyXrCDrp6TroKXsoIHsnbgg7J207JW86riw66W8IO2RnO2YhO2VmOuKlCDrsKnrspXsnYQg67O07Jes7KSN64uI64ukLiDsi5zsnpHtlZjquLAg7KKL7J2AIOqzs+ydgCBCQkPsmYAg6rO164+Z7Jy866GcIOy0rOyYgSDtlZwg7Ken7J2AIOuPmeyYgeyDgeyeheuLiOuLpC4gaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1qYmtTUkxZU29qby4KCi0gZ2FwbWluZGVyIOuNsOydtO2EsOuKlCDquLDrjIAg7IiY66qF6rO8IEdEUOyZgCDqsJnsnYAg7Ya16rOE66W867O06rOgIOyLnOqwhCDqsr3qs7zsl5Ag65Sw66W4IOq1reqwgOydmCDsp4TtlonsnYQg7JqU7JW97ZWp64uI64ukLiBnYXBtaW5kZXIg7Yyo7YKk7KeA66W8IOunjOuToCBKZW5ueSBCcnlhbiDrjZXrtoTsl5Ag642w7J207YSw64qUIFLsl5DshJwg7Im96rKMIOyVoeyEuOyKpCDtlaAg7IiYIOyeiOyKteuLiOuLpC4KCmBgYHtyfQpsaWJyYXJ5KGdhcG1pbmRlcikKZ2FwbWluZGVyCmBgYAoKLSDsnbQg7IKs66GAIOyXsOq1rOyXkOyEnCDsmrDrpqzripQgIuqwgSDqta3qsIAgKOq1reqwgCnsl5Ag64yA7ZWcIOq4sOuMgCDsiJjrqoUgKGxpZmVFeHAp7J20IOyLnOqwhOyXkCDrlLDrnbwg7Ja065a76rKMIOuzgO2VmOuKlOqwgD8i652864qUIOyniOusuOyXkCDri7XtlZjquLAg7JyE7ZW0IOyEuCDqsIDsp4Ag67OA7IiY7JeQ66eMIOy0iOygkOydhCDrp57stpwg6rKD7J6F64uI64ukLiDsi5zsnpHtlZjquLAg7KKL7J2AIOqzs+ydgCDspITqsbDrpqzsnoXri4jri6QuCgpgYGB7cn0KZ2FwbWluZGVyICU+JSAKICBnZ3Bsb3QoYWVzKHllYXIsIGxpZmVFeHAsIGdyb3VwID0gY291bnRyeSkpICsKICAgIGdlb21fbGluZShhbHBoYSA9IDEvMykKYGBgCgotIOydtOqyg+ydgCDsnpHsnYAg642w7J207YSwIOyEuO2KuOyeheuLiOuLpC4g64uo7KeAIDEsNzAwIOqwnOydmCDqtIDsuKHsuZjsmYAgMyDqsJzsnZgg67OA7IiYIOunjCDsnojsirXri4jri6QuIAoKLSDqt7jrn6zrgpgg6rOE7IaNIOynhO2WieuQmOuKlCDqsoPsnYQg67O06riw6rCAIOyXrOyghO2eiCDslrTroLXsirXri4jri6QhIOyghOuwmOyggeycvOuhnCDquLDrjIAg7IiY66qF7J20IOq+uOykgO2eiCDqsJzshKDrkJjqs6DsnojripQg6rKD7LKY65+8IOuztOyeheuLiOuLpC4gCi0g6re465+s64KYIOyekOyEuO2eiCDsgrTtjrTrs7TrqbQg7J20IO2MqO2EtOydhCDrlLDrpbTsp4Ag7JWK64qUIOq1reqwgOqwgCDsnojsnYzsnYQg7JWMIOyImCDsnojsirXri4jri6QuIOyasOumrOuKlCDslrTrlrvqsowg7J2065OkIOq1reqwgOulvOuztOuLpCDsib3qsowg67O8IOyImCDsnojsirXri4jquYw/CgotIO2VnCDqsIDsp4Ag67Cp67KV7J2AIOyngOuCnCDsnqXsl5DshJzsmYAg64+Z7J287ZWcIOygkeq3vOuyleydhCDsgqzsmqntlZjripQg6rKD7J6F64uI64ukLiAKCi0g642UIOyEuOuwgO2VnCDstpTshLjrpbwg67O07KeAIOuqu+2VmOqyjO2VmOuKlCDqsJXroKXtlZwg7Iug7Zi4ICjsoITrsJjsoIHsnbgg7ISg7ZiVIOyEseyepSnqsIAg7J6I7Iq164uI64ukLiDsmrDrpqzripQg7ISg7ZiVIOy2lOyEuOulvCDqsIDsp4Qg66qo64247J2EIO2UvO2Mhe2VqOycvOuhnOyNqCDsnbTrn6ztlZwg7JqU7IaM65Ok7J2EIOq1rOu2hO2VoCDqsoPsnoXri4jri6QuIOydtCDrqqjrjbjsnYAg7Iuc6rCE7J20IOyngOuCqOyXkCDrlLDrnbwg6r647KSA7Z6IIOyEseyepe2VmOqzoCDrgpjrqLjsp4DripQg64Ko7JWE7J6I64qUIOqyg+ydhCDrs7Tsl6zspI3ri4jri6QuCgotIOuLueyLoOydgCDsnbTrr7gg7Jqw66as6rCAIO2VmOuCmOydmCDqta3qsIDrpbwg6rCA7KGM64uk66m0IOq3uOqyg+ydhO2VmOuKlCDrspXsnYQg7JWM6rOgIOyeiOyKteuLiOuLpAoKYGBge3J9Cm56IDwtIGZpbHRlcihnYXBtaW5kZXIsIGNvdW50cnkgPT0gIk5ldyBaZWFsYW5kIikKbnogJT4lIAogIGdncGxvdChhZXMoeWVhciwgbGlmZUV4cCkpICsgCiAgZ2VvbV9saW5lKCkgKyAKICBnZ3RpdGxlKCJGdWxsIGRhdGEgPSAiKQoKbnpfbW9kIDwtIGxtKGxpZmVFeHAgfiB5ZWFyLCBkYXRhID0gbnopCm56ICU+JSAKICBhZGRfcHJlZGljdGlvbnMobnpfbW9kKSAlPiUKICBnZ3Bsb3QoYWVzKHllYXIsIHByZWQpKSArIAogIGdlb21fbGluZSgpICsgCiAgZ2d0aXRsZSgiTGluZWFyIHRyZW5kICsgIikKCm56ICU+JSAKICBhZGRfcmVzaWR1YWxzKG56X21vZCkgJT4lIAogIGdncGxvdChhZXMoeWVhciwgcmVzaWQpKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGNvbG91ciA9ICJ3aGl0ZSIsIHNpemUgPSAzKSArIAogIGdlb21fbGluZSgpICsgCiAgZ2d0aXRsZSgiUmVtYWluaW5nIHBhdHRlcm4iKQpgYGAKCiMjIyAyNS4yLjEgTmVzdGVkIGRhdGEKCi0g7J20IOy9lOuTnOulvCDsl6zrn6wg67KIIOuzteyCrO2VmOyXrCDrtpnsl6wg64Sj64qUIOqyg+ydhCDsg4Hsg4HtlbTrs7Tsi63si5zsmKQuIOq3uOufrOuCmCDri7nsi6DsnYAg7J2066+4IOuNlCDrgpjsnYAg67Cp67KV7J2EIOuwsOyboOyKteuLiOuLpCEgCgotIO2VqOyImOuhnCDqs7XthrUg7L2U65Oc66W8IOy2lOy2nO2VmOqzoCBwdXJycuydmCBtYXAg7ZWo7IiY66W8IOyCrOyaqe2VmOyXrCDrsJjrs7Xtlanri4jri6QuIOydtCDrrLjsoJzripQg7J207KCE7JeQIOuzuCDqsoPqs7wg7JW96rCEIOuLpOultOqyjCDqtazshLHrkKnri4jri6QuIAoKLSDqsIEg67OA7IiY7JeQIOuMgO2VtCDslaHshZjsnYQg67CY67O17ZWY64qUIOuMgOyLoCwg7ZaJ7J2YIO2VmOychCDsp5Htlakg7J24IOqwgSDqta3qsIDsl5Ag64yA7ZW0IOyVoeyFmOydhCDrsJjrs7Xtlanri4jri6QuIOq3uOugh+qyjO2VmOq4sCDsnITtlbTshJzripQg7IOI66Gc7Jq0IOuNsOydtO2EsCDqtazsobAg7J24IOykkeyyqSDrkJwg642w7J207YSwIO2UhOugiOyehOydtCDtlYTsmpTtlanri4jri6QuIAoKLSDspJHssqkg65CcIOuNsOydtO2EsCDtlITroIjsnoTsnYQg66eM65Ok66Ck66m0IOq3uOujue2ZlCDrkJwg642w7J207YSwIO2UhOugiOyehOycvOuhnCDsi5zsnpHtlZjsl6wgIuykkeyyqSLtlanri4jri6QuCgpgYGB7cn0KYnlfY291bnRyeSA8LSBnYXBtaW5kZXIgJT4lIAogIGdyb3VwX2J5KGNvdW50cnksIGNvbnRpbmVudCkgJT4lIAogIG5lc3QoKQoKYnlfY291bnRyeQpgYGAKCi0gKOuCmOuKlCDrjIDrpZnqs7wg6rWt6rCA66W8IOq1rOu2hO2VmOyXrCDsobDquIjslKkg67aA7KCV7ZWY6rOg7J6I64ukLiDso7zslrTsp4Qg6rWt6rCALCDrjIDrpZnsnYAg6rOg7KCV65CY7Ja0IOyeiOycvOuvgOuhnCDrjZQg7J207IOBIOq3uOujueydhCDstpTqsIDtlZjsp4Ag7JWK7KeA66eMIOy2lOqwgCDrs4DsiJjrpbwg7YOA6rOgIOyJveqyjCDtg4gg7IiY7J6I64ukLikKCi0g7J2066CH6rKM7ZWY66m0IOq3uOujueuLuSDtlZjrgpjsnZgg7ZaJICjqta3qsIAg67OEKeqzvCDslb3qsIQg7Yq57J207ZWcIOyXtCAo642w7J207YSwKeydtOyeiOuKlCDrjbDsnbTthLAg7ZSE66CI7J6E7J20IOunjOuTpOyWtOynkeuLiOuLpC4gCgotIOuNsOydtO2EsOuKlCDrjbDsnbTthLAg7ZSE66CI7J6EICjrmJDripQg7KCV7ZmV7ZWcIOqygynsnZgg66qp66Gd7J6F64uI64ukLiDsnbTqsoPsnYAg66+47LmcIOyVhOydtOuUlOyWtOyymOufvCDrs7TsnoXri4jri6QuIAoKLSDsmrDrpqzripQg64uk66W4IOuNsOydtO2EsCDtlITroIjsnoTsnZgg66qp66GdIOyduCDsl7TsnbTsnojripQg642w7J207YSwIO2UhOugiOyehOydhCDqsIDsp4Dqs6Ag7J6I7Iq164uI64ukISAKCi0g64KY64qUIOydtOqyg+ydtCDsmZwg7KKL7J2AIOyDneqwgeydtOudvOqzoCDsg53qsIHtlZjripTsp4Ag6rOnIOyEpOuqhSDtlaAg6rKD7J2064ukLgoKLSDrjbDsnbTthLAg7Je07J2AIOuLpOyGjCDrs7XsnqHtlZjquLAg65WM66y47JeQIOuztOq4sOqwgCDquYzri6Qg66Gt7Iq164uI64ukLiDsmrDrpqzripQg7Jes7KCE7Z6IIOydtOufrO2VnCDqsJzssrTrpbwg7YOQ7IOJ7ZWY64qUIOuNsCDsnKDsmqntlZwg64+E6rWs66W8IOyCrOyaqe2VmOqzoCDsnojsirXri4jri6QuIAoKLSDrtojtlontnojrj4Qgc3RyICgp7J2EIOyCrOyaqe2VmOuKlCDqsoPsnYAg6raM7J6l7ZWY7KeAIOyViuyKteuLiOuLpC4g7Jmc64OQ7ZWY66m0IOyiheyihSDrp6TsmrAg6ri0IOy2nOugpeydhCDsg53shLHtlZjquLAg65WM66y47J6F64uI64ukLiAKCi0g6re465+s64KYIOuNsOydtO2EsCDsl7Tsl5DshJwg64uo7J28IOyalOyGjOulvCDrvZHsnLzrqbQg7ZW064u5IOq1reqwgCAo7J20IOqyveyasCDslYTtlITqsIDri4jsiqTtg4Qp7J2YIOuqqOuToCDrjbDsnbTthLDqsIAg7Y+s7ZWo65CY7Ja0IOyeiOydjOydhCDslYwg7IiYIOyeiOyKteuLiOuLpC4KCmBgYHtyfQpieV9jb3VudHJ5JGRhdGFbWzFdXQpgYGAKCi0g7ZGc7KSAIOq3uOujue2ZlCDrkJwg642w7J207YSwIO2UhOugiOyehOqzvCDspJHssqkg65CcIOuNsOydtO2EsCDtlITroIjsnoTsnZgg7LCo7J207KCQ7JeQIOycoOydmO2VmOyLreyLnOyYpC4gCgotIOq3uOujue2ZlCDrkJwg642w7J207YSwIO2UhOugiOyehOyXkOyEnCDqsIEg7ZaJ7J2AIOq0gOywsOyeheuLiOuLpC4g7KSR7LKpIOuQnCDrjbDsnbTthLAg7ZSE66CI7J6E7JeQ7IScIOqwgSDtlonsnYAg6re466O57J6F64uI64ukLiAKCi0g7KSR7LKpIOuQnCDrjbDsnbTthLAg7IS47Yq47JeQIOuMgO2VtCDsg53qsIHtlbQg67O8IOyImOyeiOuKlCDrmJAg64uk66W4IOuwqeuyleydgCDsnbTsoJwg66mU7YOAIOu3sOulvCDslrvripQg6rKD7J6F64uI64ukLiAKCi0g7ZWY64KY7J2YIOyLnOygkOydtCDslYTri4wg6rWt6rCA7J2YIOyghOyytCDsi5zqsIQg7L2U7Iqk66W8IOuCmO2DgOuCtOuKlCDtlonsnoXri4jri6QuCgojIyMgMjUuMi4yIExpc3QtY29sdW1ucwoKLSDsnbTsoJwg7KSR7LKpIOuQnCDrjbDsnbTthLAg7ZSE66CI7J6E7J20IOyDneqyqOyEnCDsnbzrtoAg66qo64247J2EIOygge2Vqe2VmOqyjCDrp4zrk6Qg7IiYIOyeiOyKteuLiOuLpC4g66qo6424IOygge2VqSDtlajsiJjqsIAg7J6I7Iq164uI64ukLgoKLSDqt7jrpqzqs6Ag66qo65OgIOuNsOydtO2EsCDtlITroIjsnoTsl5Ag7KCB7Jqp7ZWY66Ck6rOg7ZWp64uI64ukLiDrjbDsnbTthLAg7ZSE66CI7J6E7J2AIOuqqeuhneyXkCDsnojsnLzrr4DroZwgcHVycnIgOjogbWFwICgp7J2EIOyCrOyaqe2VmOyXrCDqsIEg7JqU7IaM7JeQIGNvdW50cnlfbW9kZWzsnYQg7KCB7JqpIO2VoCDsiJgg7J6I7Iq164uI64ukLgoKYGBge3J9CmNvdW50cnlfbW9kZWwgPC0gZnVuY3Rpb24oZGYpIHsKICBsbShsaWZlRXhwIH4geWVhciwgZGF0YSA9IGRmKQp9Cgptb2RlbHMgPC0gbWFwKGJ5X2NvdW50cnkkZGF0YSwgY291bnRyeV9tb2RlbCkKYGBgCgotIOq3uOufrOuCmCDrqqjrjbgg66qp66Gd7J2EIOyekOycoOuhreqyjCDrlqAg64uk64uI64qUIOqwnOyytOuhnCDrgqjqsqjrkZDquLDrs7Tri6TripQgYnlfY291bnRyeSDrjbDsnbTthLAg7ZSE66CI7J6E7JeQIOyXtOuhnCDsoIDsnqXtlZjripQg6rKD7J20IOuNlCDsoovsirXri4jri6QuIAoKLSDqtIDroKgg6rCd7LK066W8IOyXtOyXkCDsoIDsnqXtlZjripQg6rKD7J2AIOuNsOydtO2EsCDtlITroIjsnoTsnZgg7ZW17IusIOu2gOu2hOydtOupsCDsmZwg66qp66GdIOyXtOydtCDqt7jroIfqsowg7KKL7J2AIOyDneqwgeyduOyngCDsg53qsIHtlanri4jri6QuIAoKLSDsnbQg6rWt6rCA65Ok6rO8IOydvO2VmOuKlCDqs7zsoJXsl5DshJwg7Jqw66as64qUIOq1reqwgOuniOuLpCDsmpTshozqsIAg7ZWY64KY7JSp7J6I64qUIOunjuydgCDrqqnroZ3snYQg6rCW6rKMIOuQoCDqsoPsnoXri4jri6QuIAoKLSDqt7jroIfri6TrqbQg7J20IOuqqOuToCDqsoPsnYQg7ZWY64KY7J2YIOuNsOydtO2EsCDtlITroIjsnoTsl5Ag66qo65GQIOyggOyepe2VmOyngCDslYrripQg7J207Jyg64qUIOustOyXh+yeheuLiOq5jD8KCi0g64uk7IucIOunkO2VtCDsoITsl60g7ZmY6rK97JeQ7IScIOyDiCDqsJ3ssrTrpbwg66eM65Oc64qUIOuMgOyLoCBieV9jb3VudHJ5IOuNsOydtO2EsCDtlITroIjsnoTsl5Ag7IOIIOuzgOyImOulvCDrp4zrk6Qg6rKD7J6F64uI64ukLiBkcGx5ciA6OiBtdXRhdGUgKCnsl5Ag64yA7ZWcIOyekeyXheyeheuLiOuLpC4KCmBgYHtyfQoKYnlfY291bnRyeSA8LSBieV9jb3VudHJ5ICU+JSAKICBtdXRhdGUobW9kZWwgPSBtYXAoZGF0YSwgY291bnRyeV9tb2RlbCkpCmJ5X2NvdW50cnkKYGBgCgotIOydtOuKlCDrqqjrk6Ag7J6l7KCQ7J20IOyeiOyKteuLiOuLpC4g7Jmc64OQ7ZWY66m0IOuqqOuToCDqtIDroKgg7Jik67iM7KCd7Yq46rCAIO2VqOq7mCDsoIDsnqXrkJjquLAg65WM66y47JeQIO2VhO2EsOunge2VmOqxsOuCmCDsoJXroKwg7ZWgIOuVjCDsiJjrj5nsnLzroZwg64+Z6riw7ZmUIO2VoCDtlYTsmpTqsIAg7JeG7Iq164uI64ukLiAKCi0g642w7J207YSwIO2UhOugiOyehOydmCDsnZjrr7jripQg64uk7J2M6rO8IOqwmeydtCDsspjrpqztlanri4jri6QuCgpgYGB7cn0KYnlfY291bnRyeSAlPiUgCiAgZmlsdGVyKGNvbnRpbmVudCA9PSAiRXVyb3BlIikKCmJ5X2NvdW50cnkgJT4lIAogIGFycmFuZ2UoY29udGluZW50LCBjb3VudHJ5KQpgYGAKCi0g642w7J207YSwIO2UhOugiOyehCDrqqnroZ3qs7wg66qo6424IOuqqeuhneydtCDrs4TqsJzsnZgg6rCd7LK0IOyduCDqsr3smrAg7ZWY64KY7J2YIOuyoe2EsOulvCDsnqzsoJXroKztlZjqsbDrgpgg7ZWY7JyEIOynke2VqSDtlaAg65WM66eI64ukIOuqqOuToCDrsqHthLAg6rCd7LK066W8IOyerOygleugrO2VmOqxsOuCmCDtlZjsnIQg7KeR7ZWp7J2EIOuPmeq4sO2ZlO2VmOyXrCDrj5nquLDtmZQg7IOB7YOc66GcIOycoOyngO2VtOyVvO2VnOuLpOuKlCDsoJDsnYQg6riw7Ja17ZW07JW87ZWp64uI64ukLiAKCi0g7J6K7Ja0IOuyhOumrOuptCDsvZTrk5zripQg6rOE7IaNIOyekeuPme2VmOyngOunjCDsnpjrqrvrkJwg64yA64u17J2EIOykhCDqsoPsnoXri4jri6QuCgojIyMgMjUuMi4zIFVubmVzdGluZwoKLSDsnbTsoITsl5DripQg64uo7J28IOuNsOydtO2EsCDshLjtirjroZwg64uo7J28IOuqqOuNuOydmCDsnpTssKjrpbwg6rOE7IKw7ZaI7Iq164uI64ukLgoKLSDsnbTsoJwgMTQyIOqwnOydmCDrjbDsnbTthLAg7ZSE66CI7J6E6rO8IDE0MiDqsJzsnZgg66qo64247J20IOyeiOyKteuLiOuLpC4g7J6U7LCo66W8IOqzhOyCsO2VmOugpOuptCBhZGRfcmVzaWR1YWxzICgp66W8IOqwgSDrqqjrjbggLSDrjbDsnbTthLAg7IyN6rO8IO2VqOq7mCDtmLjstpztlbTslbztlanri4jri6QuCgpgYGB7cn0KYnlfY291bnRyeSA8LSBieV9jb3VudHJ5ICU+JSAKICBtdXRhdGUoCiAgICByZXNpZHMgPSBtYXAyKGRhdGEsIG1vZGVsLCBhZGRfcmVzaWR1YWxzKQogICkKYnlfY291bnRyeQpgYGAKCi0g6re465+s64KYIOuNsOydtO2EsCDtlITroIjsnoQg66qp66Gd7J2EIOyWtOuWu+qyjCDqt7jrprQg7IiYIOyeiOyKteuLiOq5jD8gCgotIOq3uCDsp4jrrLjsl5Ag64u17ZWY6riwIOychO2VtCDqs6DqtbDrtoTtiKztlZjripQg64yA7IugLCDrjbDsnbTthLAg7ZSE66CI7J6EIOuqqeuhneydhCDsnbzrsJgg642w7J207YSwIO2UhOugiOyehOycvOuhnCDrj4zroKQg67O06rKg7Iq164uI64ukLiAKCi0g7J207KCE7JeQ64qUIOydvOuwmCDrjbDsnbTthLAg7ZSE66CI7J6E7J2EIOykkeyyqSDrjbDsnbTthLAg7ZSE66CI7J6E7Jy866GcIOuwlOq+uOq4sCDsnITtlbQgbmVzdCAoKeulvCDsgqzsmqntlojsnLzrqbAg7J207KCc64qUIHVubmVzdCAoKeyZgCDrsJjrjIDsnZgg7J6R7JeF7J2EIOyImO2Wie2VqeuLiOuLpC4KCmBgYHtyfQpyZXNpZHMgPC0gdW5uZXN0KGJ5X2NvdW50cnksIHJlc2lkcykKcmVzaWRzCmBgYAoKLSDqsIEg7J2867CYIOyXtOydgCDspJHssqkg7Je07J2YIOqwgSDtlonrp4jri6Qg7ZWY64KY7JSpIOuwmOuzteuQqeuLiOuLpC4KCi0g7J207KCcIOyasOumrOuKlCDsoJXqt5wg642w7J207YSwIO2UhOugiOyehOydhCDqsIDsp4Dqs6Ag7J6I7Iq164uI64ukLiDsnpTssKjrpbwg6re466a0IOyImCDsnojsirXri4jri6QuCgpgYGB7cn0KcmVzaWRzICU+JSAKICBnZ3Bsb3QoYWVzKHllYXIsIHJlc2lkKSkgKwogICAgZ2VvbV9saW5lKGFlcyhncm91cCA9IGNvdW50cnkpLCBhbHBoYSA9IDEgLyAzKSArIAogICAgZ2VvbV9zbW9vdGgoc2UgPSBGQUxTRSkKIz4gYGdlb21fc21vb3RoKClgIHVzaW5nIG1ldGhvZCA9ICdnYW0nCmBgYAoKLSDrjIDrpZkg67OEIGZhY2V0dGluZ+ydgCDtirntnogg65Oc65+s64Kp64uI64ukIDoKCmBgYHtyfQpyZXNpZHMgJT4lIAogIGdncGxvdChhZXMoeWVhciwgcmVzaWQsIGdyb3VwID0gY291bnRyeSkpICsKICAgIGdlb21fbGluZShhbHBoYSA9IDEgLyAzKSArIAogICAgZmFjZXRfd3JhcCh+Y29udGluZW50KQpgYGAKCi0g6rCA67K87Jq0IO2MqO2EtOydhCDrhpPsuZwg6rKD7LKY65+8IOuztOyeheuLiOuLpC4g7JWE7ZSE66as7Lm07JeQ7ISc64+EIOqzhOyGjSDsp4TtlonspJHsnbgg7Z2l66+466Gc7Jq0IOygkOydtCDsnojsirXri4jri6QuIOunpOyasCDtgbAg7J6U7LCo6rCAIOyeiOydjOydhCDslYwg7IiYIOyeiOyKteuLiOuLpC4gCgotIOydtOuKlCDsmrDrpqwg66qo64247J20IOqxsOq4sOyXkOyEnCDsnpgg66ee7KeAIOyViuuKlOuLpOuKlCDqsoPsnYQg7J2Y66+47ZWp64uI64ukLiDsmrDrpqzripQg64uk7J2MIOyEueyFmOyXkOyEnCDsooAg642UIOuLpOuluCDqsIHrj4Tsl5DshJwg6rO16rKpIO2VtCDrs7TqsqDsirXri4jri6QuCgojIyMgMjUuMi40IE1vZGVsIHF1YWxpdHkKCi0g66qo64247JeQ7IScIOyelOywqOulvCDrs7TripQg64yA7IugIOuqqOuNuCDtkojsp4jsl5Ag64yA7ZWcIOydvOuwmOyggeyduCDsuKHsoJXsnYQg67O8IOyImCDsnojsirXri4jri6QuIAoKLSDsnbTsoIQg7J6l7JeQ7IScIOuqhyDqsIDsp4Ag6rWs7LK07KCB7J24IOy4oeyglSDrsKnrspXsnYQg67Cw7Jug7Iq164uI64ukLiDsl6zquLDsl5DshJzripQgYnJvb20g7Yyo7YKk7KeA66W8IOyCrOyaqe2VmOuKlCDri6Trpbgg7KCR6re8IOuwqeuyleydhCDrs7Tsl6zspI3ri4jri6QuIAoKLSBicm9vbSDqvrjrn6zrr7jripQg66qo64247J2EIOq5lOuBlO2VnCDrjbDsnbTthLDroZwg67CU6r646riw7JyE7ZWcIOydvOuwmOyggeyduCDquLDriqUg7IS47Yq466W8IOygnOqzte2VqeuLiOuLpC4gCgotIOyXrOq4sOyEnOuKlCBicm9vbSA6OiBnbGFuY2UgKCnrpbwg7IKs7Jqp7ZWY7JesIOydvOu2gCDrqqjrjbgg7ZKI7KeIIOuplO2KuOumreydhCDstpTstpztlanri4jri6QuIAoKLSDrqqjrjbjsl5Ag7KCB7Jqp7ZWY66m0IOuLqOydvCDtlonsnbTsnojripQg642w7J207YSwIO2UhOugiOyehOydtCDsg53shLHrkKnri4jri6QuCgpgYGB7cn0KYnJvb206OmdsYW5jZShuel9tb2QpCmBgYAoKYGBge3J9CmJ5X2NvdW50cnkgJT4lIAogIG11dGF0ZShnbGFuY2UgPSBtYXAobW9kZWwsIGJyb29tOjpnbGFuY2UpKSAlPiUgCiAgdW5uZXN0KGdsYW5jZSkKYGBgCgotIOyXrOyghO2eiCDrqqjrk6Ag66qp66GdIOyXtOydhCDtj6ztlajtlZjquLAg65WM66y47JeQIOyasOumrOqwgCDsm5DtlZjripQg6rKw6rO866y87J20IOyVhOuLmeuLiOuLpC4gdW5uZXN0ICgp6rCAIOuLqOydvCDtlokg642w7J207YSwIO2UhOugiOyehOyXkOyEnCDsnpHrj5kg7ZWgIOuVjOydmCDquLDrs7gg64+Z7J6R7J6F64uI64ukLiDsnbQg7Je07J2EIOyWteygnO2VmOugpOuptCAuZHJvcCA9IFRSVUXrpbwg7IKs7Jqp7ZWp64uI64ukLgoKYGBge3J9CmdsYW5jZSA8LSBieV9jb3VudHJ5ICU+JSAKICBtdXRhdGUoZ2xhbmNlID0gbWFwKG1vZGVsLCBicm9vbTo6Z2xhbmNlKSkgJT4lIAogIHVubmVzdChnbGFuY2UsIC5kcm9wID0gVFJVRSkKZ2xhbmNlCmBgYAoKLSAo7J247IeE65CY7KeAIOyViuydgCDrs4DsiJjsl5Dso7zsnZjrpbwg6riw7Jq47J207Iut7Iuc7JikLiDsnKDsmqntlZwg7KCV67O06rCAIOunjuydtCDsnojsirXri4jri6QuKQoKLSDsnbQg642w7J207YSwIO2UhOugiOyehOydhCDsgqzsmqntlZjrqbQg7J6YIOunnuyngCDslYrripQg66qo64247J2EIOywvuydhCDsiJgg7J6I7Iq164uI64ukLgoKYGBge3J9CmdsYW5jZSAlPiUgCiAgYXJyYW5nZShyLnNxdWFyZWQpCmBgYAoKLSDstZzslYXsnZgg66qo64247J2AIOuqqOuRkCDslYTtlITrpqzsubTsl5DsnojripQg6rKD7LKY65+8IOuztOyeheuLiOuLpC4gCgotIOq3uOqxuCDtlIzroa/snLzroZwg65GQIOuyiCDtmZXsnbjtlbQg67SF7Iuc64ukLiDsl6zquLDsl5DripQg7IOB64yA7KCB7Jy866GcIOyggeydgCDsiJjsnZgg6rSA7LihIOqwkuqzvCDsnbTsgrAg67OA7IiY6rCAIOyeiOycvOuvgOuhnCBnZW9tX2ppdHRlciAoKeqwgCDtmqjqs7zsoIHsnoXri4jri6QuCgpgYGB7cn0KZ2xhbmNlICU+JSAKICBnZ3Bsb3QoYWVzKGNvbnRpbmVudCwgci5zcXVhcmVkKSkgKyAKICAgIGdlb21faml0dGVyKHdpZHRoID0gMC41KQpgYGAKCi0gV2UgY291bGQgcHVsbCBvdXQgdGhlIGNvdW50cmllcyB3aXRoIHBhcnRpY3VsYXJseSBiYWQgUjIgYW5kIHBsb3QgdGhlIGRhdGE6CgpgYGB7cn0KYmFkX2ZpdCA8LSBmaWx0ZXIoZ2xhbmNlLCByLnNxdWFyZWQgPCAwLjI1KQoKZ2FwbWluZGVyICU+JSAKICBzZW1pX2pvaW4oYmFkX2ZpdCwgYnkgPSAiY291bnRyeSIpICU+JSAKICBnZ3Bsb3QoYWVzKHllYXIsIGxpZmVFeHAsIGNvbG91ciA9IGNvdW50cnkpKSArCiAgICBnZW9tX2xpbmUoKQpgYGAKCi0g7Jqw66as64qUIEhJViAvIEFJRFMg7KCE7Je867OR6rO8IOultOyZhOuLpCDrjIDrn4kg7ZWZ7IK07J2YIOu5hOq3ueydtOudvOuKlCDrkZAg6rCA7KeAIOyjvOyalCDtmqjqs7zrpbwg7Jes6riw7JeQ7IScIOuztOyVmOyKteuLiOuLpC4KCiMjIyAyNS4yLjUgRXhlcmNpc2VzICjsg53rnrUpCgojIyMgMjUuMyBMaXN0LWNvbHVtbnMKCi0g7J207KCc64qUIOyXrOufrCDrqqjrjbjsnYQg6rSA66as7ZWY6riwIOychO2VnCDquLDrs7gg7JuM7YGsIO2UjOuhnOulvCDrs7TslZjsnLzrr4DroZwg66qHIOqwgOyngCDshLjrtoAg7IKs7ZWt7Jy866GcIOuPjOyVhOqwgCDrs7TqsqDsirXri4jri6QuIAoKLSDsnbQg7IS57IWY7JeQ7ISc64qUIOuqqeuhnSDsl7Qg642w7J207YSwIOq1rOyhsOyXkCDrjIDtlbQg7KKAIOuNlCDsnpDshLjtnogg7IK07Y60IOuztOqyoOyKteuLiOuLpC4gCgotIOy1nOq3vOyXkCDrgpjripQg66qp66GdIOyXtOyXkCDrjIDtlZwg7JWE7J2065SU7Ja066W8IOygleunkOuhnCDrhpLsnbQg7Y+J6rCA7ZaI7Iq164uI64ukLiDrqqnroZ0gLSDsl7TsnYAg642w7J207YSwIO2UhOugiOyehOydmCDsoJXsnZjsl5Ag64K07Y+s65CY7Ja0IOyeiOyKteuLiOuLpC4gCgotIOuNsOydtO2EsCDtlITroIjsnoTsnYAg64+Z7J287ZWcIOq4uOydtCDrsqHthLDsnZgg66qF66qFIOuQnCDrqqnroZ3snoXri4jri6QuIAoKLSDrqqnroZ3snYAg67Kh7YSw7J2066+A66GcIOuqqeuhneydhCAK642w7J207YSwIO2UhOugiOyehOydmCDsl7TroZwg7IKs7Jqp7ZWY64qUIOqyg+ydtCDtla3sg4Eg7Jis67CU66W4IOuwqeuyleyeheuLiOuLpC4gCgotIOq3uOufrOuCmCDquLDrs7ggUuydgCDrqqnroZ0g7Je07J2EIOyJveqyjCDrp4zrk6Qg7IiYIOyXhuycvOupsCBkYXRhLmZyYW1lICgp7J2AIOuqqeuhneydhCDsl7Qg66qp66Gd7Jy866GcIOyymOumrO2VqeuLiOuLpC4KYGBge3J9CmRhdGEuZnJhbWUoeCA9IGxpc3QoMTozLCAzOjUpKQpgYGAKCmBgYHtyfQpkYXRhLmZyYW1lKAogIHggPSBJKGxpc3QoMTozLCAzOjUpKSwgCiAgeSA9IGMoIjEsIDIiLCAiMywgNCwgNSIpCikKYGBgCgotIFRpYmJsZeydgCBsYXppZXIgKHRpYmJsZSAoKeydtCDsnoXroKXsnYQg7IiY7KCV7ZWY7KeAIOyViuydjCkg67CPIOuNlCDrgpjsnYAg7J247IeEIOuwqeuyleydhCDsoJzqs7XtlZjsl6zsnbQg66y47KCc66W8IOyZhO2ZlO2VqeuLiOuLpC4KCmBgYHtyfQp0aWJibGUoCiAgeCA9IGxpc3QoMTozLCAzOjUpLCAKICB5ID0gYygiMSwgMiIsICIzLCA0LCA1IikKKQpgYGAKCmBgYHtyfQp0cmliYmxlKAogICB+eCwgfnksCiAgMTozLCAiMSwgMiIsCiAgMzo1LCAiMywgNCwgNSIKKQpgYGAKCi0g66qp66GdIC0g7Je07J2AIOyiheyihSDspJHqsIQg642w7J207YSwIOq1rOyhsOuhnCDqsIDsnqUg7Jyg7Jqp7ZWp64uI64ukLiAKCi0g64yA67aA67aE7J2YIFIg7ZWo7IiY64qUIOybkOyekCDrsqHthLAg65iQ64qUIOuNsOydtO2EsCDtlITroIjsnoTsl5DshJwg7J6R64+Z7ZWY6riwIOuVjOusuOyXkCDsp4HsoJEg7J6R7JeF7ZWY6riw6rCAIOyWtOugteyngOunjCDqtIDroKgg7ZWt66qp7J2EIOuNsOydtO2EsCDtlITroIjsnoTsl5Ag7Jyg7KeA7ZWY64qUIOydtOygkOydgCDslb3qsITsnZgg67KI6rGwIOuhnOybgOydtCDrlLDrpoXri4jri6QuCgotIOydvOuwmOyggeycvOuhnCDtmqjqs7zsoIHsnbgg66qp66GdIC0g7Je0IO2MjOydtO2UhCDrnbzsnbjsnZgg7IS4IOu2gOu2hOydtCDsnojsirXri4jri6QuCgotIGxpc3QtY29sdW1ucyDrp4zrk6TquLDsl5Ag7ISk66qFIOuQnCDqsoPsspjrn7wgbmVzdCAoKSwgc3VtbWFyaXplICgpICsgbGlzdCAoKSDrmJDripQgbXV0YXRlICgpICsgbWFwIO2VqOyImCDspJEg7ZWY64KY66W8IOyCrOyaqe2VmOyXrCBsaXN0LWNvbHVtbuydhCDrp4zrk63ri4jri6QuCgotIG1hcCAoKSwgbWFwMiAoKSDrmJDripQgcG1hcCAoKeydhCDsgqzsmqntlZjsl6wg6riw7KG0IOuqqeuhnSDsl7TsnYQg67OA7ZiV7ZWY7JesIOuLpOuluCDspJHqsIQg66qp66GdIOyXtOydhCDsnpHshLHtlanri4jri6QuIAoKLSDsmIjrpbwg65Ok7Ja0LCDsnITsnZgg7IKs66GAIOyXsOq1rOyXkOyEnCDrjbDsnbTthLAg7ZSE66CI7J6E7J2YIOuqqeuhnSAtIOyXtOydhCDrs4DtmJXtlZjsl6wg66qo64247J2YIOuqqeuhnSAtIOyXtOydhCDrp4zrk6Tsl4jsirXri4jri6QuCgotIOuqqeuhnSDsl7Qg64uo7Iic7ZmU7JeQ7IScIOyEpOuqhe2VnOuMgOuhnCDrqqnroZ0g7Je07J2EIOuNsOydtO2EsCDtlITroIjsnoQg65iQ64qUIOybkOyekCDrsqHthLDroZwg64uk7IucIOuLqOyInO2ZlO2VqeuLiOuLpC4KCiMjIyAyNS40IENyZWF0aW5nIGxpc3QtY29sdW1ucwoKLSDsnbzrsJjsoIHsnLzroZwgdGliYmxlICgp7J2EIOyCrOyaqe2VmOyXrCDrqqnroZ0g7Je07J2EIOunjOuTpOyngCDslYrsirXri4jri6QuIAoKLSDrjIDsi6Ag64uk7J2MIOyEuCDqsIDsp4Ag67Cp67KVIOykkSDtlZjrgpjrpbwg7IKs7Jqp7ZWY7JesIOydvOuwmCDsl7Tsl5DshJwg7IOd7ISx7ZWp64uI64ukLgoKLSB0aWR5ciA6OiBuZXN0ICgp66W8IOyCrOyaqe2VmOyXrCDqt7jro7ntmZQg65CcIOuNsOydtO2EsCDtlITroIjsnoTsnYQg642w7J207YSwIO2UhOugiOyehCDrqqnroZ0gLSDsl7TsnbTsnojripQg7KSR7LKpIOuNsOydtO2EsCDtlITroIjsnoTsnLzroZwg67OA7ZmY7ZWp64uI64ukLgoKLSBtdXRhdGUgKCkg67CPIOuyoe2EsO2ZlCDrkJwg7ZWo7IiY66W8IOyCrOyaqe2VmOyXrCDrqqnroZ3snYQg67CY7ZmY7ZWp64uI64ukLgoKLSDsl6zrn6wg6rKw6rO866W8IOuwmO2ZmO2VmOuKlCBzdW1tYXJpemUgKCkg67CPIOyalOyVvSDtlajsiJguCgotIOuYkOuKlCB0aWJibGUgOjogZW5mcmFtZSAoKeydhCDsgqzsmqntlZjsl6wg66qF66qFIOuQnCDrqqnroZ3sl5DshJwg7IOd7ISxIO2VoCDsiJjrj4Qg7J6I7Iq164uI64ukLgoKLSDsnbzrsJjsoIHsnLzroZwg66qp66GdIOyXtOydhCDrp4zrk6Qg65WMIOuPmeyniOyEseyduOyngCDtmZXsnbjtlbTslbztlanri4jri6QuIOqwgSDsmpTshozsl5DripQg64+Z7J287ZWcIOycoO2YleydmCDqsoPsnbQg7Y+s7ZWo65CY7Ja07JW87ZWp64uI64ukLiAKCi0g7J206rKD7J20IOyCrOyLpOyduOyngCDtmZXsnbjtlZjripQg6rKA7IKs64qUIOyXhuyngOunjCwgcHVycnLsnYQg7IKs7Jqp7ZWY6rOgIO2DgOyehSDslYjsoJUg7ZWo7IiY7JeQIOuMgO2VtCDrsLDsmrQg6rKD7J2EIOq4sOyWte2VnOuLpOuptCwg7J6Q7Jew7Iqk65+96rKMIOuwnOqyrOuQmOyWtOyVvO2VqeuLiOuLpC4KCiMjIyAyNS40LjEgV2l0aCBuZXN0aW5nCgotIG5lc3QgKCnripQg642w7J207YSwIO2UhOugiOyehOydmCDrqqnroZ0g7Je07J207J6I64qUIOuNsOydtO2EsCDtlITroIjsnoQg7J24IOykkeyyqSDrjbDsnbTthLAg7ZSE66CI7J6E7J2EIOunjOuTreuLiOuLpC4KCi0g7KSR7LKpIOuQnCDrjbDsnbTthLAg7ZSE66CI7J6E7JeQ7IScIOqwgSDtlonsnYAg66mU7YOAIOq0gOy4oeyeheuLiOuLpC4g64uk66W4IOyXtOydgCDqtIDsuKHsnYQg7KCV7J2Y7ZWY64qUIOuzgOyImCAo7JyE7J2YIOq1reqwgCDrsI8g64yA66WZ6rO8IOqwmeydgCnrpbwg7KCc6rO17ZWY6rOgIOuNsOydtO2EsCDtlITroIjsnoTsnZgg66qp66GdIOyXtOydgCDrqZTtg4Ag6rSA7Lih7J2EIOq1rOyEse2VmOuKlCDqsJzrs4Qg6rSA7Lih7J2EIOygnOqzte2VqeuLiOuLpC4KCi0gbmVzdCAoKeulvCDsgqzsmqntlZjripQg65GQIOqwgOyngCDrsKnrspXsnbQg7J6I7Iq164uI64ukLiAKCi0g7KeA6riI6rmM7KeAIOq3uOujue2ZlCDrkJwg642w7J207YSwIO2UhOugiOyehOqzvCDtlajqu5gg7IKs7Jqp7ZWY64qUIOuwqeuyleydhCDsgrTtjrQg67O07JWY7Iq164uI64ukLiDqt7jro7ntmZQg65CcIOuNsOydtO2EsCDtlITroIjsnoTsl5Ag7KCB7Jqp65CY66m0IG5lc3QgKCnripQg6re466O57ZmUIOyXtOydhCDqt7jrjIDroZwg7Jyg7KeA7ZWY6rOgIOq3uCDsmbgg66qo65OgIO2VreuqqeydhCBsaXN0LWNvbHVtbuyXkCDrrLbsirXri4jri6QuCgpgYGB7cn0KZ2FwbWluZGVyICU+JSAKICBncm91cF9ieShjb3VudHJ5LCBjb250aW5lbnQpICU+JSAKICBuZXN0KCkKYGBgCgotIOuYkO2VnCDqt7jro7ntmZTrkJjsp4Ag7JWK7J2AIOuNsOydtO2EsCDtlITroIjsnoTsl5DsnbQg7Je07J2EIOyCrOyaqe2VmOyXrCDspJHssqkg7ZWgIOyXtOydhCDsp4DsoJXtlaAg7IiYIOyeiOyKteuLiOuLpC4KCmBgYHtyfQpnYXBtaW5kZXIgJT4lIAogIG5lc3QoeWVhcjpnZHBQZXJjYXApCmBgYAoKIyMjIDI1LjQuMiBGcm9tIHZlY3RvcmlzZWQgZnVuY3Rpb25zCgotIOycoOyaqe2VnCDtlajsiJgg7KSRIOydvOu2gOuKlCDsm5DsnpAg67Kh7YSw66W8IOyCrOyaqe2VmOyXrCDrqqnroZ3snYQg67CY7ZmY7ZWp64uI64ukLiAKCi0g7JiI66W8IOuTpOyWtCwg66y47J6Q7Je07JeQ7IScIOusuOyekCDrsqHthLDrpbwg7Leo7ZWY6rOgIOusuOyekCDrsqHthLAg66qp66Gd7J2EIOuwmO2ZmO2VmOuKlCBzdHJpbmdyIDo6IHN0cl9zcGxpdCAoKeyXkCDrjIDtlbQg67Cw7Jug7Iq164uI64ukLgoKLSBtdXRhdGUg64K067aA7JeQ7IScIOydtOulvCDsgqzsmqntlZjrqbQgbGlzdC1jb2x1bW7snYQg7Ja77J2EIOyImCDsnojsirXri4jri6QuCgpgYGB7cn0KZGYgPC0gdHJpYmJsZSgKICB+eDEsCiAgImEsYixjIiwgCiAgImQsZSxmLGciCikgCgpkZiAlPiUgCiAgbXV0YXRlKHgyID0gc3RyaW5ncjo6c3RyX3NwbGl0KHgxLCAiLCIpKQoKYGBgCgpgYGB7cn0KZGYgJT4lIAogIG11dGF0ZSh4MiA9IHN0cmluZ3I6OnN0cl9zcGxpdCh4MSwgIiwiKSkgJT4lIAogIHVubmVzdCgpCmBgYAoKLSAo7J20IO2MqO2EtOydhCDrp47snbQg7IKs7Jqp7ZWY64qUIOqyveyasCzsnbQg6rO17Ya1IO2MqO2EtOydhCDqsJDsi7jripQg656Y7Y28IOyduCB0aWR5ciA6IHNlcGFyYXRlX3Jvd3MgKCnrpbwg7ZmV7J247ZWY7Iut7Iuc7JikLgoKLSDsnbQg7Yyo7YS07J2YIOuLpOuluCDsmIjripQgcHVycnLsl5DshJwgbWFwICgpLCBtYXAyICgpLCBwbWFwICgp7J2EIOyCrOyaqe2VmOuKlCDqsoPsnoXri4jri6QuIOyYiOulvCDrk6TslrQsIOuLpOuluCDtlajsiJjrpbwg7Zi47Lac7ZWY7JesIOuniOyngOuniSDsmIjsoJzrpbwg6rCA7KC4IOyZgOyEnCBtdXRhdGUgKCnrpbwg7IKs7Jqp7ZWY64+E66GdIOuLpOyLnCDsnpHshLHtlaAg7IiYIOyeiOyKteuLiOuLpC4KCmBgYHtyfQpzaW0gPC0gdHJpYmJsZSgKICB+ZiwgICAgICB+cGFyYW1zLAogICJydW5pZiIsIGxpc3QobWluID0gLTEsIG1heCA9IC0xKSwKICAicm5vcm0iLCBsaXN0KHNkID0gNSksCiAgInJwb2lzIiwgbGlzdChsYW1iZGEgPSAxMCkKKQoKc2ltICU+JQogIG11dGF0ZShzaW1zID0gaW52b2tlX21hcChmLCBwYXJhbXMsIG4gPSAxMCkpCgpgYGAKCi0g6riw7Iig7KCB7Jy866GcIHNpbeydgCDrkZAg67Cw7JmAIOygleyImCDrsqHthLDrpbwg66qo65GQIO2PrO2VqO2VmOqzoCDsnojquLAg65WM66y47JeQIOq3oOyniO2VmOyngCDslYrsirXri4jri6QuIAoKLSDqt7jrn6zrgpgg7KCV7IiYIOuwjyDrs7Xsi53snYAg66qo65GQIOyIq+yekCDrsqHthLDsnbTrr4DroZwg66eO7J2AIOusuOygnOqwgCDrsJzsg53tlZjsp4DripQg7JWK7Iq164uI64ukLgoKIyMjIDI1LjQuMyBGcm9tIG11bHRpdmFsdWVkIHN1bW1hcmllcwoKLSBzdW1tYXJpemUgKCnsnZgg7ZWcIOqwgOyngCDsoJztlZwg7IKs7ZWt7J2AIOuLqOydvCDqsJLsnYQg66as7YS07ZWY64qUIOyalOyVvSDtlajsiJjsl5DshJzrp4wg7J6R64+Z7ZWc64uk64qUIOqyg+yeheuLiOuLpC4gCgotIOymiSwg7J6E7J2Y7J2YIOq4uOydtOydmCDrsqHthLDrpbwg66as7YS07ZWY64qUIHF1YW50aWxlICgp6rO8IOqwmeydgCDtlajsiJjsmYAg7ZWo6ruYIOyCrOyaqe2VoCDsiJgg7JeG64uk64qUIOqyg+ydhCDsnZjrr7jtlanri4jri6QuCgpgYGB7cn0KbXRjYXJzICU+JSAKICBncm91cF9ieShjeWwpICU+JSAKICBzdW1tYXJpc2UocSA9IHF1YW50aWxlKG1wZykpCmBgYAoKLSDqt7jrn6zrgpgg66qp66Gd7JeQIOqysOqzvOulvCDrnpjtlZEg7ZWgIOyImOuKlCDsnojsirXri4jri6QuIOydtOqyg+ydgCDqsIEg7JqU7JW97J20IOydtOygnCDquLjsnbQgMeydmCDrqqnroZ0gKOuyoe2EsCnsnbTrr4DroZwgc3VtbWFyaXplICgp7J2YIOqzhOyVveydhCDrlLDrpoXri4jri6QuCgpgYGB7cn0KbXRjYXJzICU+JSAKICBncm91cF9ieShjeWwpICU+JSAKICBzdW1tYXJpc2UocSA9IGxpc3QocXVhbnRpbGUobXBnKSkpCgpgYGAKCi0g67aI7Lap67aEIO2VnCDqsrDqs7zrpbwg7Ja77Jy866Ck66m0IOuLpOydjOqzvCDqsJnsnYAg6rCA64ql7ISx7J2EIO2PrOywqe2VtOyVvO2VqeuLiOuLpC4KCmBgYHtyfQpwcm9icyA8LSBjKDAuMDEsIDAuMjUsIDAuNSwgMC43NSwgMC45OSkKbXRjYXJzICU+JSAKICBncm91cF9ieShjeWwpICU+JSAKICBzdW1tYXJpc2UocCA9IGxpc3QocHJvYnMpLCBxID0gbGlzdChxdWFudGlsZShtcGcsIHByb2JzKSkpICU+JSAKICB1bm5lc3QoKQpgYGAKCiMjIyAyNS40LjQgRnJvbSBhIG5hbWVkIGxpc3QKCi0g66qp66GdIOyXtOydtOyeiOuKlCDrjbDsnbTthLAg7ZSE66CI7J6E7J2AIOydvOuwmOyggeyduCDrrLjsoJzsl5Ag64yA7ZWcIO2VtOqysOyxheydhCDsoJzqs7Xtlanri4jri6QuIAoKLSDrqqnroZ3snZgg64K07Jqp6rO8IO2VtOuLuSDsmpTshozrpbwg67CY67O1IO2VoCDqsr3smrAg7Ja065a76rKM7ZWp64uI6rmMPyDrqqjrk6Ag6rKD7J2EIO2VmOuCmOydmCDqsJ3ssrTroZwg66y264qUIOuMgOyLoCDrjbDsnbTthLAg7ZSE66CI7J6E7J2EIOunjOuTnOuKlCDqsoPsnbQg642UIOyJveyKteuLiOuLpC4gCgotIO2VnCDsl7Tsl5DripQg7JqU7IaM6rCAIO2PrO2VqOuQoCDsiJgg7J6I6rOgIO2VnCDsl7Tsl5DripQg66qp66Gd7J20IO2PrO2VqOuQoCDsiJgg7J6I7Iq164uI64ukLiAKCi0g66qp66Gd7JeQ7IScIOq3uOufrO2VnCDrjbDsnbTthLAg7ZSE66CI7J6E7J2EIOyDneyEse2VmOuKlCDsiazsmrQg67Cp67KV7J2AIHRpYmJsZSA6OiBlbmZyYW1lICgp7J6F64uI64ukLgoKYGBge3J9CnggPC0gbGlzdCgKICBhID0gMTo1LAogIGIgPSAzOjQsIAogIGMgPSA1OjYKKSAKCmRmIDwtIGVuZnJhbWUoeCkKZGYKYGBgCgotIOydtCDqtazsobDsnZgg7J6l7KCQ7J2AIOqwhOuLqO2VqeuLiOuLpC4g7J2066aE7J2AIOuplO2DgCDrjbDsnbTthLDsnZgg66y47J6QIOuyoe2EsOqwgCDsnojsnLzrqbQg7Jyg7Jqp7ZWY7KeA66eMIOuLpOuluCDsnKDtmJXsnZgg642w7J207YSw6rCAIOyeiOqxsOuCmCDsl6zrn6wg67Kh7YSw6rCAIOyeiOycvOuptCDrj4Tsm4DsnbQg65CY7KeAIOyViuyKteuLiOuLpC4KCi0g7J207KCcIOydtOumhOqzvCDqsJLsnYQg67OR66Cs66GcIOuwmOuzte2VmOugpOuKlCDqsr3smrAgbWFwMigp66W8IOyCrOyaqe2VoCDsiJgg7J6I7Iq164uI64ukLgoKYGBge3J9CmRmICU+JSAKICBtdXRhdGUoCiAgICBzbXJ5ID0gbWFwMl9jaHIobmFtZSwgdmFsdWUsIH4gc3RyaW5ncjo6c3RyX2MoLngsICI6ICIsIC55WzFdKSkKICApCmBgYAoKIyMjIDI1LjQuNSBFeGVyY2lzZXMgKOyDneuetSkKCiMjIyAyNS41IFNpbXBsaWZ5aW5nIGxpc3QtY29sdW1ucwoKLSDsnbQg7LGF7JeQ7IScIOuwsOyboOuNmCDrjbDsnbTthLAg7KGw7J6RIOuwjyDsi5zqsIHtmZQg6riw7Iig7J2EIOyggeyaqe2VmOugpOuptCBsaXN0LWNvbHVtbuydhCDsnbzrsJgg7Je0ICjsm5DsnpAg67Kh7YSwKSDrmJDripQg7Je0IOynke2VqeycvOuhnCDri6Tsi5wg64uo7Iic7ZmU7ZW07JW87ZWp64uI64ukLiAKCi0g642UIOqwhOuLqO2VnCDqtazsobDroZwg64uk7IucIOy2leyGjO2VmOq4sCDsnITtlbQg7IKs7Jqp7ZWY64qUIOq4sOyIoOydgCDsmpTshowg64u5IO2VmOuCmOydmCDqsJIg65iQ64qUIOyXrOufrCDqsJIg7KSRIOybkO2VmOuKlCDqsJLsl5Ag65Sw6528IOuLpOumheuLiOuLpC4KCi0g64uo7J28IOqwkuydhCDsm5DtlaAg6rK97JqwIG1hcF9sZ2wgKCksIG1hcF9pbnQgKCksIG1hcF9kYmwgKCkg67CPIG1hcF9jaHIgKCnsl5AgbXV0YXRlICgp66W8IOyCrOyaqe2VmOyXrCDsm5DsnpAg67Kh7YSw66W8IOunjOuTreuLiOuLpC4KCi0g66eO7J2AIOqwkuydhCDsm5DtlZjrqbQgdW5uZXN0ICgp66W8IOyCrOyaqe2VmOyXrCDrqqnroZ0g7Je07J2EIOydvOuwmCDsl7TroZwg64uk7IucIOuzgO2ZmO2VmOqzoCDtlYTsmpTtlZzrp4ztgbwg7ZaJ7J2EIOuwmOuzte2VmOyLreyLnOyYpC4KCiMjIyAyNS41LjEgTGlzdCB0byB2ZWN0b3IKCi0g66qp66GdIOyXtOydhCDsm5DsnpAg67Kh7YSw66GcIOykhOydvCDsiJgg7J6I7Jy866m0IOydvOuwmCDsl7TsnbTrkKnri4jri6QuIOyYiOulvCDrk6TslrQsIO2DgOyeheqzvCDquLjsnbTrpbwg6rCA7KeEIOqwneyytOulvCDtla3sg4Eg7JqU7JW9IO2VoCDsiJgg7J6I7Jy866+A66GcLOydtCDsvZTrk5zripQg7Jes65+s67aE7J20IOqwgOyngOqzoOyeiOuKlCBsaXN0LWNvbHVtbuydmCDsooXrpZjsl5Ag6rSA6rOE7JeG7J20IOyekeuPme2VqeuLiOuLpCA6CgpgYGB7cn0KZGYgPC0gdHJpYmJsZSgKICB+eCwKICBsZXR0ZXJzWzE6NV0sCiAgMTozLAogIHJ1bmlmKDUpCikKICAKZGYgJT4lIG11dGF0ZSgKICB0eXBlID0gbWFwX2Nocih4LCB0eXBlb2YpLAogIGxlbmd0aCA9IG1hcF9pbnQoeCwgbGVuZ3RoKQopCmBgYAoKLSDsnbTqsoPsnYAg6riw67O4IHRibCDsnbjsh4Qg67Cp67KV7JeQ7IScIOyWu+ydgCDquLDrs7gg7KCV67O07JmAIOuPmeydvO2VmOyngOunjCDtlYTthLDrp4HsnYQg7JyE7ZW0IOyCrOyaqe2VoCDsiJgg7J6I7Iq164uI64ukLgoKLSDsnbTquLDsooUg66qp66Gd7J2EIOqwgOyngOqzoCDsnojqs6Ag6re4IOu2gOu2hOydhCDqsbjrn6wg64K06rOgIOyLtuuLpOuptCDsnKDsmqntlZwg6riw67KV7J6F64uI64ukLgoKLSDsp4Drj4QgXyAqICgpIOuLqOy2le2CpOulvCDsnorsp4Ag66eI7IS47JqULiBtYXBfY2hyICh4LCAiYXBwbGUiKeydhCDsgqzsmqntlZjsl6wgeOydmCDqsIEg7JqU7IaM7JeQIOuMgO2VtCBhcHBsZeyXkCDsoIDsnqXrkJwg66y47J6Q7Je07J2EIOy2lOy2nCDtlaAg7IiYIOyeiOyKteuLiOuLpC4gCgotIOykkeyyqSDrkJwg66qp66Gd7J2EIOydvOuwmCDsl7TroZwg64GM7Ja0IOyYrCDrlYwg7Jyg7Jqp7ZWp64uI64ukLiBudWxs66W8IOuwmO2ZmO2VmOuKlCDrjIDsi6Ag7JqU7IaM6rCAIOuIhOudvSDrkJwg6rK97JqwIOyCrOyaqe2VoCDqsJLsnYQg7KCc6rO17ZWY66Ck66m0IC5udWxsIOyduOyImOulvCDsgqzsmqntlZjsi63si5zsmKQuCgpgYGB7cn0KZGYgPC0gdHJpYmJsZSgKICB+eCwKICBsaXN0KGEgPSAxLCBiID0gMiksCiAgbGlzdChhID0gMiwgYyA9IDQpCikKZGYgJT4lIG11dGF0ZSgKICBhID0gbWFwX2RibCh4LCAiYSIpLAogIGIgPSBtYXBfZGJsKHgsICJiIiwgLm51bGwgPSBOQV9yZWFsXykKKQpgYGAKCiMjIyAyNS41LjIgVW5uZXN0aW5nCgotIHVubmVzdCAoKeuKlCBsaXN0LWNvbHVtbuydmCDqsIEg7JqU7IaM7JeQIOuMgO2VtCDtlZwg67KI7JSpIOydvOuwmCDsl7TsnYQg67CY67O17ZWY7JesIOyekeuPme2VqeuLiOuLpC4g7JiI66W8IOuTpOyWtCwg64uk7J2M7J2YIOyVhOyjvCDqsITri6jtlZwg7JiI7KCc7JeQ7IScIOyyqyDrsojsp7gg7ZaJ7J2EIDQg67KIIOuwmOuzte2VqeuLiOuLpCAoeeydmCDssqsg67KI7Ke4IOyalOyGjOuKlCDquLjsnbTqsIAgNOydtOuvgOuhnCkuIOuRkCDrsojsp7gg7ZaJ7J2AIO2VnCDrsojrp4wg67CY67O17ZWp64uI64ukLgoKYGBge3J9CnRpYmJsZSh4ID0gMToyLCB5ID0gbGlzdCgxOjQsIDEpKSAlPiUgdW5uZXN0KHkpCmBgYAoKLSDspoksIOuLpOuluCDsiJjsnZgg7JqU7IaM6rCAIO2PrO2VqCDrkJwg65GQIOqwnOydmCDsl7TsnYQg64+Z7Iuc7JeQIOykkeyyqSDtlbTsoJwg7ZWgIOyImCDsl4bsirXri4jri6QuCgpgYGB7cn0KZGYxIDwtIHRyaWJibGUoCiAgfngsIH55LCAgICAgICAgICAgfnosCiAgIDEsIGMoImEiLCAiYiIpLCAxOjIsCiAgIDIsICJjIiwgICAgICAgICAgIDMKKQpkZjEKCmRmMSAlPiUgdW5uZXN0KHksIHopCgpkZjIgPC0gdHJpYmJsZSgKICB+eCwgfnksICAgICAgICAgICB+eiwKICAgMSwgImEiLCAgICAgICAgIDE6MiwgIAogICAyLCBjKCJiIiwgImMiKSwgICAzCikKZGYyCgojZGYyICU+JSB1bm5lc3QoeSwgeikKYGBgCgotIOuNsOydtO2EsCDtlITroIjsnoTsnZgg66qp66GdIOyXtOydhCDqtITtmLjsl5Ag64Sj7J2EIOuVjOuPhCDrj5nsnbztlZwg7JuQ7LmZ7J20IOyggeyaqeuQqeuLiOuLpC4g6rCBIO2WieydmCDrqqjrk6Ag642w7J207YSwIO2UhOugiOyehOydtCDqsJnsnYAg7IiY7J2YIO2WieydhCDqsIDsp4Qg7ZWcIOyXrOufrCBsaXN0LWNvbOydhCDspJHssqkg7ZWgIOyImCDsnojsirXri4jri6QuCgojIyMgMjUuNS4zIEV4ZXJjaXNlcyAo7IOd6561KQoKIyMjIDI1LjYgTWFraW5nIHRpZHkgZGF0YSB3aXRoIGJyb29tCgotIGJyb29tIO2MqO2CpOyngOuKlCDrqqjrjbjsnYQg6rmU64GU7ZWcIOuNsOydtO2EsCDtlITroIjsnoTsnLzroZwg67CU6r646riw7JyE7ZWcIOyEuCDqsIDsp4Ag7J2867CY7KCB7J24IOuPhOq1rOulvCDsoJzqs7Xtlanri4jri6QuCgotIGJyb29tIDo6IGdsYW5jZSAobW9kZWwpIOqwgSDrqqjrjbjsl5Ag64yA7ZWcIO2WieydhCDrsJjtmZjtlanri4jri6QuIOqwgSDsl7TsnYAg66qo6424IOyalOyVveydhCDsoJzqs7Xtlanri4jri6QuIOuqqOuNuCDsmpTslb0g65iQ64qUIOuqqOuNuCDrs7XsnqHshLEg65iQ64qUIOuRmOydmCDsobDtlansnoXri4jri6QuCgotIGJyb29tIDo6IHRpZHkgKG1vZGVsKSDrqqjrjbjsnZgg6rCBIOqzhOyImOyXkCDrjIDtlZwg7ZaJ7J2EIOuwmO2ZmO2VqeuLiOuLpC4g6rCBIOyXtOydgCDstpTsoJXsuZgg65iQ64qUIOq3uCDrs4Drj5nshLHsl5Ag64yA7ZWcIOygleuztOulvCDsoJzqs7Xtlanri4jri6QuCgotIGJyb29tIDo6IGF1Z21lbnQgKG1vZGVsLCBkYXRhKeuKlCDrjbDsnbTthLDsnZgg6rCBIO2WieyXkCDrjIDtlbQg7ZaJ7J2EIOuwmO2ZmO2VmOqzoCDsnpTsl6zsmYAg6rCZ7J2AIOy2lOqwgCDqsJLsnYQg7LaU6rCA7ZWY66mwIO2GteqzhOyXkCDsmIHtlqXsnYQg7KSN64uI64ukLg==